From 21dbdf69a02a803a52372b13948dd02ea8e43d13 Mon Sep 17 00:00:00 2001 From: babio Date: Tue, 4 Jun 2024 05:54:55 -0700 Subject: [PATCH 1/4] IFC 25.2 for Revit 2025 --- .../Autodesk.SteelConnections.ASIFC.dll | Bin 197408 -> 197920 bytes .../IFCExporterUIOverride.dll | Bin 0 -> 360736 bytes .../Revit.IFC.Export.dll | Bin 0 -> 4063776 bytes .../Revit.IFC.Import.dll | Bin 0 -> 526112 bytes .../Resources/ADSKIFCExporterHelp.htm | 157 +- .../bundle/PackageContents.xml | 12 +- Install/RevitIFCSetupWix/Product.wxs | 42 +- .../RevitIFCSetupWix/RevitIFCSetupWix.wixproj | 2 +- Install/RevitIFCSetupWix/buildInstaller.bat | 8 +- Revit.IFC.sln | 16 +- .../IFCCategoryMapping.xaml | 342 + .../IFCCategoryMapping.xaml.cs | 1337 +++ .../IFCCopyCategoryTemplate.xaml | 33 + .../IFCCopyCategoryTemplate.xaml.cs | 35 + .../IFCDeleteCategoryTemplate.xaml | 31 + .../IFCDeleteCategoryTemplate.xaml.cs | 41 + .../IFCNewCategoryTemplate.xaml | 34 + .../IFCNewCategoryTemplate.xaml.cs | 36 + .../IFCRenameCategoryTemplate.xaml | 38 + .../IFCRenameCategoryTemplate.xaml.cs | 37 + .../IFCCategoryTemplateData.cs | 166 + .../IFCCommandOverrideApplication.cs | 37 +- .../IFCEntityTree/BrowseIFCEntityServer.cs | 8 +- .../IFCEntityTree/EntityTree.xaml | 1 + .../IFCEntityTree/EntityTree.xaml.cs | 544 +- .../IFCEnumExtensions.cs | 115 + .../IFCExporterUIOverride/IFCExport.xaml.cs | 5 +- .../IFCExportConfiguration.cs | 195 +- .../IFCExportConfigurationsMap.cs | 112 +- .../IFCExporterUI.csproj | 225 +- .../IFCExporterUIOverride/IFCExporterUI.props | 18 +- .../IFCExporterUIOverride.csproj | 269 +- .../IFCExporterUIOverride.props | 25 - .../IFCExporterUIWindow.xaml | 283 +- .../IFCExporterUIWindow.xaml.cs | 261 +- .../IFCExporterUIOverride/IFCFacilityTypes.cs | 321 + .../IFCPhaseAttributes.cs | 2 +- .../IFCRenameExportSetup.xaml | 2 +- .../Properties/AssemblyInfo.cs | 7 +- .../Properties/Resources.Designer.cs | 713 +- .../Properties/Resources.resx | 236 +- .../Properties/Settings.Designer.cs | 4 +- .../icons/arrow_down.png | Bin 0 -> 374 bytes .../icons/arrow_right.png | Bin 0 -> 373 bytes .../icons/data-refresh.png | Bin 0 -> 444 bytes Source/IFCExporterUIOverride/icons/load.ico | Bin 17726 -> 21822 bytes Source/IFCExporterUIOverride/icons/save.ico | Bin 17726 -> 21822 bytes Source/IFCExporterUIOverride/packages.config | 4 - .../Enums/IFCKnownMVDAndER.cs | 14 +- .../Extension/IFCAddressItem.cs | 24 +- .../Extension/IFCClassification.cs | 6 +- .../Extension/IFCFileHeader.cs | 49 +- .../Properties/AssemblyInfo.cs | 10 +- .../Revit.IFC.Common/Revit.IFC.Common.csproj | 130 +- .../Revit.IFC.Common/Revit.IFC.Common.props | 25 - .../Utility/AllocatedGeometryObjectCache.cs | 116 +- .../Utility/COBieCompanyInfo.cs | 8 +- .../Utility/COBieProjectInfo.cs | 8 +- .../Utility/IFCAnyHandleUtil.cs | 61 + .../Utility/IfcSchemaEntityTree.cs | 53 +- Source/Revit.IFC.Common/Utility/MathUtil.cs | 9 +- .../Revit.IFC.Common/Utility/OptionsUtil.cs | 3 + .../Utility/SolidMeshGeometryInfo.cs | 591 +- .../Exporter/AssemblyInstanceExporter.cs | 4 +- .../Revit.IFC.Export/Exporter/BeamExporter.cs | 31 +- .../Revit.IFC.Export/Exporter/BodyExporter.cs | 1072 ++- .../Exporter/CeilingExporter.cs | 36 +- .../Exporter/CurtainSystemExporter.cs | 214 +- .../Exporter/CurveElementExporter.cs | 229 +- Source/Revit.IFC.Export/Exporter/Exporter.cs | 1810 +--- .../Exporter/ExporterInitializer.cs | 240 +- .../Exporter/ExtrusionExporter.cs | 99 +- .../Exporter/FamilyInstanceExporter.cs | 251 +- .../Exporter/FilledRegionExporter.cs | 2 +- .../Exporter/FloorExporter.cs | 29 +- .../Exporter/GenericElementExporter.cs | 20 +- .../Exporter/GenericMEPExporter.cs | 5 +- .../Revit.IFC.Export/Exporter/GridExporter.cs | 9 +- .../Exporter/HostObjectExporter.cs | 27 +- .../Exporter/HostedSweepExporter.cs | 114 +- .../Exporter/IFCEntityAndPsetList.cs | 7 +- .../Revit.IFC.Export/Exporter/PartExporter.cs | 70 +- .../Calculators/GrossAreaCalculator.cs | 17 +- .../Calculators/GrossCeilingAreaCalculator.cs | 43 + .../Calculators/GrossFloorAreaCalculator.cs | 43 + .../Calculators/GrossVolumeCalculator.cs | 48 +- .../Calculators/HeightCalculator.cs | 2 +- .../Calculators/IsExternalCalculator.cs | 8 +- .../Calculators/LengthCalculator.cs | 2 +- .../Calculators/NetFloorAreaCalculator.cs | 51 + .../Calculators/WidthCalculator.cs | 4 +- .../PropertySet/ClassificationUtil.cs | 48 +- .../Exporter/PropertySet/Description.cs | 40 +- .../ElectricalCurrentPropertyUtil.cs | 121 - .../ElectricalVoltagePropertyUtil.cs | 121 - .../PropertySet/FrequencyPropertyUtil.cs | 107 - .../PositivePlaneAnglePropertyUtil.cs | 136 - .../PropertySet/PreDefinedPropertySetEntry.cs | 2 - .../Exporter/PropertySet/PropertySetEntry.cs | 202 +- .../PropertySet/PropertySetEntryMap.cs | 467 +- .../Exporter/PropertySet/PropertyUtil.cs | 8266 +++++++++-------- .../Exporter/ProxyElementExporter.cs | 2 +- .../Exporter/RailingExporter.cs | 2 +- .../Revit.IFC.Export/Exporter/RampExporter.cs | 16 +- .../Exporter/RebarCouplerExporter.cs | 23 +- .../Exporter/RebarExporter.cs | 6 +- .../Revit.IFC.Export/Exporter/RoofExporter.cs | 394 +- .../Exporter/SpatialElementExporter.cs | 320 +- .../Exporter/StairsExporter.cs | 328 +- .../Exporter/StructuralMemberExporter.cs | 4 +- .../Exporter/SweptSolidExporter.cs | 60 +- .../Exporter/TextNoteExporter.cs | 2 +- .../Revit.IFC.Export/Exporter/WallExporter.cs | 283 +- .../Exporter/WallSweepExporter.cs | 4 +- Source/Revit.IFC.Export/Exporter/ZoneInfo.cs | 174 +- .../Properties/AssemblyInfo.cs | 10 +- .../Properties/Resources.Designer.cs | 2 +- .../Revit.IFC.Export/Revit.IFC.Export.csproj | 401 +- .../Revit.IFC.Export/Revit.IFC.Export.props | 25 - .../Revit.IFC.Export/Toolkit/IFCDataUtil.cs | 191 +- .../Toolkit/IFCInstanceExporter.cs | 343 +- .../Toolkit/PlacementSetter.cs | 6 +- .../Revit.IFC.Export/Utility/CategoryUtil.cs | 44 +- .../DoorWindowDelayedOpeningCreator.cs | 47 +- .../DoorWindowDelayedOpeningCreatorCache.cs | 28 +- .../Utility/DoorWindowInfo.cs | 10 +- .../Utility/ElementFilteringUtil.cs | 406 +- .../Utility/ElementTypeToHandleCache.cs | 8 +- .../Utility/ExportOptionsCache.cs | 135 +- .../Utility/ExporterCacheManager.cs | 99 +- .../Revit.IFC.Export/Utility/ExporterUtil.cs | 589 +- .../Utility/FamilyExporterUtil.cs | 59 +- .../Revit.IFC.Export/Utility/FootPrintInfo.cs | 6 +- Source/Revit.IFC.Export/Utility/GUIDUtil.cs | 2 +- .../Revit.IFC.Export/Utility/GeometryUtil.cs | 306 +- .../Utility/IFCExportInfoPair.cs | 199 +- .../Utility/LevelInfoCache.cs | 29 + Source/Revit.IFC.Export/Utility/MEPCache.cs | 4 +- .../Utility/MaterialLayerSetInfo.cs | 225 +- Source/Revit.IFC.Export/Utility/NamingUtil.cs | 18 +- .../Revit.IFC.Export/Utility/OpeningUtil.cs | 6 +- .../Utility/ParamExprResolverParser.g4 | 28 +- .../Revit.IFC.Export/Utility/ParameterUtil.cs | 38 +- .../Utility/ProductWrapper.cs | 33 +- .../Utility/PropertyInfoCache.cs | 168 +- .../Revit.IFC.Export/Utility/PropertyMap.cs | 396 +- .../Utility/RepresentationUtil.cs | 8 +- .../Utility/SimpleSweptSolidAnalyzer.cs | 218 +- .../Utility/TriangleMergeUtil.cs | 193 +- .../Utility/TypeObjectsCache.cs | 2 +- .../Utility/UnitMappingUtil.cs | 1367 +++ Source/Revit.IFC.Export/Utility/UnitUtil.cs | 42 +- Source/Revit.IFC.Export/Utility/UnitsCache.cs | 182 +- .../Properties/AssemblyInfo.cs | 6 +- .../Revit.IFC.Import.Core.csproj | 64 +- .../Revit.IFC.Import.Core.props | 25 - Source/Revit.IFC.Import/Data/IFCBlock.cs | 4 +- .../Data/IFCBooleanOperand.cs | 31 +- .../Revit.IFC.Import/Data/IFCBooleanResult.cs | 2 +- .../Data/IFCBuildingElementProxy.cs | 2 +- .../Data/IFCBuildingStorey.cs | 2 +- .../Data/IFCConnectedFaceSet.cs | 4 +- .../Data/IFCDistributionPort.cs | 7 + Source/Revit.IFC.Import/Data/IFCElement.cs | 7 - .../Data/IFCExtrudedAreaSolid.cs | 4 +- Source/Revit.IFC.Import/Data/IFCGrid.cs | 2 +- Source/Revit.IFC.Import/Data/IFCGridAxis.cs | 2 +- .../Data/IFCHybridRepresentationItem.cs | 112 - Source/Revit.IFC.Import/Data/IFCImportFile.cs | 9 +- .../Data/IFCIndexedPolyCurve.cs | 2 +- Source/Revit.IFC.Import/Data/IFCLocation.cs | 15 +- Source/Revit.IFC.Import/Data/IFCMappedItem.cs | 2 - Source/Revit.IFC.Import/Data/IFCMaterial.cs | 21 +- Source/Revit.IFC.Import/Data/IFCObject.cs | 13 +- .../Data/IFCObjectDefinition.cs | 37 +- Source/Revit.IFC.Import/Data/IFCProduct.cs | 182 +- Source/Revit.IFC.Import/Data/IFCProfileDef.cs | 4 +- Source/Revit.IFC.Import/Data/IFCProject.cs | 26 +- .../Data/IFCRepresentation.cs | 77 +- .../Data/IFCRepresentationItem.cs | 88 +- .../Data/IFCRepresentationMap.cs | 30 +- Source/Revit.IFC.Import/Data/IFCSite.cs | 18 +- .../Data/IFCSpatialElement.cs | 86 + .../Data/IFCSpatialStructureElement.cs | 8 +- .../Revit.IFC.Import/Data/IFCSpatialZone.cs | 79 + Source/Revit.IFC.Import/Data/IFCStyledItem.cs | 5 - .../Data/IFCSweptDiskSolid.cs | 2 +- .../Data/IFCTriangulatedFaceSet.cs | 2 +- Source/Revit.IFC.Import/Data/IFCTypeObject.cs | 4 +- .../Revit.IFC.Import/Data/IFCTypeProduct.cs | 31 +- Source/Revit.IFC.Import/Data/IFCUnit.cs | 364 +- Source/Revit.IFC.Import/Data/IFCZone.cs | 5 +- .../Enums/IFCSchemaVersion.cs | 3 +- .../Geometry/IFCGeometryUtil.cs | 45 +- Source/Revit.IFC.Import/Importer.cs | 62 +- .../Properties/AssemblyInfo.cs | 13 +- .../Revit.IFC.Import/Revit.IFC.Import.csproj | 338 +- .../Revit.IFC.Import/Revit.IFC.Import.props | 25 - .../Utility/IFCCategoryUtil.cs | 73 +- .../Utility/IFCImportCache.cs | 2 + .../Utility/IFCImportHybridInfo.cs | 499 +- .../Utility/IFCImportOptions.cs | 27 +- .../Utility/ParametersToSet.cs | 49 +- .../Utility/ProcessIFCRelation.cs | 22 - Source/RevitIFCTools/IFCEntityListWin.xaml.cs | 4 +- Source/RevitIFCTools/MainWindow.xaml.cs | 3 +- .../RevitIFCTools/Properties/AssemblyInfo.cs | 7 +- .../Properties/Resources.Designer.cs | 2 +- Source/RevitIFCTools/RevitIFCTools.csproj | 254 +- .../ICSharpCode/ICSharpCode.SharpZipLib.DLL | Bin 212552 -> 258048 bytes VSProps/Revit.CSharp.Sdk.props | 6 + VSProps/Revit.CSharp.Sdk.targets | 21 + VSProps/Revit.Common.Sdk.props | 40 + VSProps/Revit.Common.Sdk.targets | 37 + VSProps/Revit.NetVersion.props | 6 + 215 files changed, 18367 insertions(+), 12904 deletions(-) create mode 100644 Install/Program Files to Install/IFCExporterUIOverride.dll create mode 100644 Install/Program Files to Install/Revit.IFC.Export.dll create mode 100644 Install/Program Files to Install/Revit.IFC.Import.dll create mode 100644 Source/IFCExporterUIOverride/IFCCategoryMapping/IFCCategoryMapping.xaml create mode 100644 Source/IFCExporterUIOverride/IFCCategoryMapping/IFCCategoryMapping.xaml.cs create mode 100644 Source/IFCExporterUIOverride/IFCCategoryMapping/IFCCopyCategoryTemplate.xaml create mode 100644 Source/IFCExporterUIOverride/IFCCategoryMapping/IFCCopyCategoryTemplate.xaml.cs create mode 100644 Source/IFCExporterUIOverride/IFCCategoryMapping/IFCDeleteCategoryTemplate.xaml create mode 100644 Source/IFCExporterUIOverride/IFCCategoryMapping/IFCDeleteCategoryTemplate.xaml.cs create mode 100644 Source/IFCExporterUIOverride/IFCCategoryMapping/IFCNewCategoryTemplate.xaml create mode 100644 Source/IFCExporterUIOverride/IFCCategoryMapping/IFCNewCategoryTemplate.xaml.cs create mode 100644 Source/IFCExporterUIOverride/IFCCategoryMapping/IFCRenameCategoryTemplate.xaml create mode 100644 Source/IFCExporterUIOverride/IFCCategoryMapping/IFCRenameCategoryTemplate.xaml.cs create mode 100644 Source/IFCExporterUIOverride/IFCCategoryTemplateData.cs delete mode 100644 Source/IFCExporterUIOverride/IFCExporterUIOverride.props create mode 100644 Source/IFCExporterUIOverride/IFCFacilityTypes.cs create mode 100644 Source/IFCExporterUIOverride/icons/arrow_down.png create mode 100644 Source/IFCExporterUIOverride/icons/arrow_right.png create mode 100644 Source/IFCExporterUIOverride/icons/data-refresh.png delete mode 100644 Source/IFCExporterUIOverride/packages.config delete mode 100644 Source/Revit.IFC.Common/Revit.IFC.Common.props rename Source/{Revit.IFC.Export => Revit.IFC.Common}/Utility/AllocatedGeometryObjectCache.cs (86%) rename Source/{Revit.IFC.Export => Revit.IFC.Common}/Utility/SolidMeshGeometryInfo.cs (60%) delete mode 100644 Source/Revit.IFC.Export/Exporter/PropertySet/ElectricalCurrentPropertyUtil.cs delete mode 100644 Source/Revit.IFC.Export/Exporter/PropertySet/ElectricalVoltagePropertyUtil.cs delete mode 100644 Source/Revit.IFC.Export/Exporter/PropertySet/FrequencyPropertyUtil.cs delete mode 100644 Source/Revit.IFC.Export/Exporter/PropertySet/PositivePlaneAnglePropertyUtil.cs delete mode 100644 Source/Revit.IFC.Export/Revit.IFC.Export.props create mode 100644 Source/Revit.IFC.Export/Utility/UnitMappingUtil.cs delete mode 100644 Source/Revit.IFC.Import.Core/Revit.IFC.Import.Core.props delete mode 100644 Source/Revit.IFC.Import/Data/IFCHybridRepresentationItem.cs create mode 100644 Source/Revit.IFC.Import/Data/IFCSpatialElement.cs create mode 100644 Source/Revit.IFC.Import/Data/IFCSpatialZone.cs delete mode 100644 Source/Revit.IFC.Import/Revit.IFC.Import.props create mode 100644 VSProps/Revit.CSharp.Sdk.props create mode 100644 VSProps/Revit.CSharp.Sdk.targets create mode 100644 VSProps/Revit.Common.Sdk.props create mode 100644 VSProps/Revit.Common.Sdk.targets create mode 100644 VSProps/Revit.NetVersion.props diff --git a/Install/Program Files to Install/Autodesk.SteelConnections.ASIFC.dll b/Install/Program Files to Install/Autodesk.SteelConnections.ASIFC.dll index 5d1825ae75b7d6410360035d11b5b1f55ebd4cdc..a868c86f3d3488a16ba732ffd2ca44f14fd02286 100644 GIT binary patch literal 197920 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 Sd0pG%73ouvk*e>9LH`RQlK7nf literal 197408 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 z%0D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%0D{67mYxam4EamUo-_#R{l|!FIs>oEC1+3 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 diff --git a/Install/Program Files to Install/IFCExporterUIOverride.dll b/Install/Program Files to Install/IFCExporterUIOverride.dll new file mode 100644 index 0000000000000000000000000000000000000000..db6f693c9104bc23cb6d5ed979fad89715c2c5d6 GIT binary patch literal 360736 zcmb@P34kO;mG`r=sCvi`#ZCwyi7W1f0ZXX=u6 zbYc6PXHK1W&czo;mrb2}!Bl(O#ZwnuJoTuPA3gQV===*dj*OHy#7UoWr01RgeBZnN zm$%-O%6rP(I|lTU+jn%!EBfv4jl==I-^&Im*V)&mB{?(> z_m(@yRO0s%NDm;_jzMonnkfD=2ED00dnm_TJm_uidH?TSQ=WHBCf3HwE_n83_-=!a^UAZw`Qa!;`CSsqN9zUhs(bt1E5QL&@x$GK`60CcQXQmv zw7VePiHv)hA|oQ@8NW+%`8H86iKYRB-y&i(gR7hi_u$nU^>dvN$DDF(4EY^u$$4TT zX7L+pv*I8@)BqGUdH5k&1+)6+L1)f896Bj=CAV!Q1eb&DEukvsz@HBaAa^zjvX>ws zGFp!IG3UN=ZsOtB=SU#`u+l3&y!2?G4==sa!%GjjcIo*Z#p^3?v>!!q+!~lo*d z2$d}y61#|_I(;i|{l$FVAB5I9u2O4prK*D4*Cmzb!omZToUzITfa=#@^U#O}g&?d@ zoEsHqOX?4|D$apCASx?0mcc!}3@ozwdy&UoM5FoPm-irL9**p~ypIGy<(1$j<&`^I zUiq`-m49J*EzZtfd25Q3Ew2!=t)!hPuaKSJl~?|3d4K1a8`qKFm1wpK7K658jmxS$ zI#|WER_k}I`B|k~8;PMb*}TI&B!gQ?p@(LmV=45o478d;X=Z6|<0b^gQLP2UXh(8P0l8N)|%F2jKXOid#_kQ{f3CzE3=YFVM`Bg6^EB4H4Y69!VGsF@VgT&3w# zk5pn(^|Cog5p!Y{(C8Eu+;shys4HqGwK)h5!f)|dWIvoroH@mo{cu|1i4#OLdiH~m zg6J`TqQ~-xQBGfs@;ITK(L*_NG0Is&d3+D$35!vlD3m7&C8YeZp`vzhCuP&0Bf#&{ zE@IW!Bg^lu2Aa{2jTGt0X|8^EI)(Pg^}91Ev`3-e-6Msbok<}~p+>6JgWugVg`Sha zolT+V0<|_eKqcwVl_JCSSa*o$(RpB}np*{l@dS_Y3_2em@fjn{?+TpNG3MV_(Khiw ze~3$t4VmhU(-a$GsA@2ViVZRJ{2o+nh@q;=7*}kFp%?U^VnYmlN&=M;`p`CLfAMx{ zgQ`$u(yueoc(Klut9{$jI`h$SeMo1bEFQMbd;z#G=XWc=ck}xG*QsGP*wO;9!}a&V!c{&`ma7Gj?XflY4KilGYL{RgWfgpIxiiy`o*7t?CDy& z=6jdiHeGLTu=hlJqrF$QH`{wv`w4o_DU~!%_=cPp5GVYZy(hv)*n4I88(;8MVKL8p zZlmIKE`rQChA%juCg|XrTGlt%@Mz=2+q^WhBUJw zlP)9%(W#bO!@h&L42=yTg>RH=LyaVEq^vEdaC3Nx@*DNL$C6(mx)fidSg4;dR0#IH z%kQ4pBdkqOr^6$9>EA&nvkuL9a!>)_6$ zpEJDu$-EYA$35$J<*7Rl@{{+@%MsOR6hoq`!77h=;SQy>yW>&{yhcD6stT+}&%xKA zF!I&R=Qx+5CuxYCDX>3{=k}!`pG(j0N|Yk2_nP08v{}dNLZj!Uh>>bx%XPlzjSr0v z*AnTv7N}G9YYOel5coKv!Jn@{bWNG@i^<{(cY$s2Mc6Oe1-8K#VPBVGuPd~7^e8cS z54)aFetj1Ig*|+OFM)qU7XRfve1m84OU;Qw`wbw3Fsl*XsCdSNlxZ(Xlj>)h!Fx%? zOnYgHy}rz36*DhmR@zRGFXUS0Wca+d=}PkQ=CkqZX708`_t6;65}wY6YWnn z1=`MRibHv$wY;rGm>Twp;p7X)(DI<{zY9|J7NWpK3`5P+g@fOvd^TGNQ=dD?s6AZ_m^TBS5 zaEt`?rLOaYdLXeRI1(&yKG-t_CnQ)@^_H$9B`QSqMYX_rO`yhL7qvd8rh|g%o~HLn z*j;k??L%|uW$HXo*rOG;8)4=Ea7uzKhu=OuMLx~%o(jlJMKddE^8-pjz}a7sf*cER znnS)#c5Ava@Z0nTE^EL2{KTm=9-}lwp&Wku{n;>vo{mCum@b4%UeR>n=>(R8p+YWv z8`W{yM(S(Wze>#MXB=c<3#IID2E(=`&%jp?Ez&E@qyWKJ=)IzXEE)9{(ahe@v^ipiU;k2EvEe` z3GGH?Y?;#>gV~#x2+2k7qHy86dCd5sp&2hPfu|+aLHINk&^Hs;w?44*FCfpIDHgbn z^rcBhI)_#UNDxNB`MBMBjKg{lvC2Vf$oc+NK0j#X#v4Hpp}EW9QKE4*^Avv|@3PhZ zc}nBi_@eg-<6B^a7BgrK%(`e8bSYNBnbr>P{lpk9Mjzlc(pX)JK8T}=1gF^a-B$pc zDMcUR)%wBCa;X`Vq7UP_C!X`U1Gh_}I@s8=GUyU4(Z@t53%kfdzAX#T+m z5tcl{l6S)5GK{{e#D*Iy$A-hN$vILPsYh2T=15H~BOu@|0$MwFj*bn_*N}_VNdngq z>~}9j&Wh33!EtS}w>mkCJRP>5iH` zV}YDCWzyX4ch7-eIpp33%zpRWtatVSUzI%Ohuvrk9NLVbPrxD$#6XC*y0z%Cs{R0wMIW6 zyvgXtJg>pSz{A`-vjH!+fbaxyUdq7_kH#5mS+QWqFN7!YE;M6pd@nH)9de)C=$X8y z1+(SQ+L>l5h_!5|()S~Lx)scr9L?o@G``7LbUy*xs8@feP}eXGrK2`uB0Ri#8HvF+ z2{BFJVg*n~LC{qSE2IAeu5nniT5|HuOX9s5=6a>5ZK#8wPPZmzf&gn7nmRueE!AL7 z0qEmFjdBAX8ofn7Ca|{8S^ep`q+GKqG&YPCT(c@x22mkDAx3L?rC4(E=T34f2OWYj zxBTd*zzWgNcn(u(J9sxQ#c_=sPc20B!GZdaV5H4nurRe88TZdWdrSQM; zSk0o|T!wc5>BGMQ0FtZ}Xc#gElCBUr%y}%+Y5k2kHR-aRoRxFi_Mp`d6_D{l^b4YG zE5fbeBL1R@*hmRyDQZEf^>!*qD_3t6(96HXT}3kj3!3K^qsxU96iw6;`PjE7A1*;U zgHm%19YQ%kUVcRq&CyD!lJ9jziL`uX=hl8{DMpu&!}xrzl7Dh@o%0!yRRpFvg3$C5 zaiPsUvsmg;CMrXI3{#5;AHyTs$irv-Qi5*~>on1|12kUWyVN`6Jx*k_PH?D)4u+Sx zR<72V&TY?Gld8{bXW*Nk4>qK&YKKC?0%@Xn%VPtsM=s1dD$P#QxO!amVjXxgg(!uy zprYa$%4makLPn|$w!8sfNyb>P`a1OqOeBCa@j(rGI6-KPsh=Bnm_J3n2>&ify|jaXBPr*hQ!&g`dtF^(Xa6^G4DLT z!IShs>YNl{9n#Acpg87Rs^3ZzQ-@}r2X-Cjw=SQ>aeilU_V>fb8~H{llWy`MqXlm} zGFpT8^!}}q@A||>(a)KwV7+7K_arf7y%~h`YZ!W}RA@1tD^f&xR{`o_Bx}_`QmC%X z=HGE|#@%5IQ^swYr+`k_f!}GKf@vPYQ0D=!{oHGRUd7HIL5u!ZaR)PssMy#(R&?2- ze-fqPa$2#mV6-<1729DJREH9RDno#J)Rg}YHMS!y0Nto5M+>MScQu=>&vN2l%nB6@ zv9KSyUM!yt!vy#f@sPX3&ZN^|G~;<}9drVSTm6{&s|~<37dMJqf6`ZIW!Z~~?l)6U zO5Tlnj1{I`g3g05aN6};)8S$CZqc8~dbrsA7*gx@S{1EF8=(#DAgH+>$2D?H6pGPu zEm!SJ8o1ZW{RrH$g9g!{o;P87?gU`Yq;jn$ENbZc7t$CigazgKSKNiw;oo?*_sx5k zIIF9@KTaDAMe{<4Ahz6^EJUbKNDNucE|0kGxD@$#cIIYwda%uOxaXbft$C)G!*m-^ ze~8iOt%M$zdk%EA6`q^q9$4aA?*J*V^dU{@lTBXPl)~c)>D%JlvS`W1ka?td`u`JGOEmbd$BlHthXyt6;l2eEc&c=22B(D-V zdL_rVLhtH+dgJ+vLU<737QUaTRw=_pO+;Z?Iaw|lq18OiYzHXKC*d%meQc>msT+D6 zk%3eP12{Vb*)gxLBytrSJ~h)SLKsdF@HpySyL&S9u7O_c1ZHS*)~zD>jH7a9$0TDP zslcH^vsf?{sJR@e!r?+QR)i}y6&U; z3H@=-^~a^gO3U5)=oB^>N{uImu+!qcY4Nh3Lq;wjG;gZt;l>-vJG1lBg&j^cpLd4n zU_PV&gT`KCfz$tLSJv$mE5+tYW|xL4c|gCCXh2P+P%v^pH#_I^*f~K~BfBy;_jGTU zlx*6GO39C5{g!2FGrZk9=*LbqOP)`m&L;ciIWEh$A;s))t2RF$9rJKwb!tjBmzP4+Nzg3%LCG>E$T)G&!V#9wAb3IMQGhkKNM~~_ z8^|}Oe7nz}3v=sbalCwC7SdkN}Q7=YxwD;h=d2=A?L?D8MY5PiA#XWnU>Av>iD1 zoDWVF4)&RO{b}VdyVk)^UkDc&6o~51=Iuo4@4(?r7XLZ^iaE4T zo(+C97M3!mV87p40dv9*s9FSirV67aHFE$!9Xo(I07MDE8~`p!0Ot6J-&GzfHmze> z1qegeT4TgHwYMdxpW%owG-WATX20m(xs4%t8+8Up(}m9?QiH+Ub9wvi@5$D@8mFQ{ zb)JPEd*?Q;A*vwG-z@my^M&V!u+`8n6S@j#4yr7i`|FJ99U^zW}}_2Ru9 zh9>KHi{i1SCD`IMt%LoL5(iO@im1)|u`HboUHWr@+Y8B5MqpDJd-kR>6k?Nu+l&1; zv%;y9==2VSgp{%|dm7WXR1o}Bo;jQGxA~4E$ZI$22jEWNM=ws1Y_6i*SjN1;*C^mn z!ObAzy$f&ar}RBuwik9bqR*&e&3>+*(LBNN3(~(~VfytneQnMNS_LLrvFkK3V)@*+ z>wGpGv{XKfu7c*_e)#{ZJX7A9hmp^sa`pJuU!Gm^t(VVnez=nQi`(dnD37F`R^-Ik z9I`2B58m!pckBXTtKtj6++I$kp@d^TX!RsUAx>h3`f)b)Bt{`7G0|$0EH_4jXblcc zt}}pSHRMC8`=9S*{tUDD!+7pV>isNl)n#sNPxVgo)folm(L`IWd8H#S7OF?5mF|QJ z*?Km_^SVl}o|!m|{3R3YE-R>b1A2D?QGdaw{qk@`$hIIV~+XmxZF%h4AMDQEU|>Hj>p?KeQ1 zd*^P~dve)X&p=Gv-(p8+JsI5a0En~Wv#UBxu$Qk)PBAV_Y4{&bN%QnmkT3(EbC=Nt za;7lcoxB*zGDm`BG3#HxLG;d+$B}pIrZkpvYilDG?=vnQ9cj54gkNA+FMGvT*&r;9 z@&J|hKBUMGU$3XHQ7EQ5@|7N?lsks(M^X`kr*gzDD#p2@^YEBgzSiZFsD}7S{1T5v z0iP0Lyfz(@P`pJh*>e$QVCsLe=Xa2$*bbJf{XdKC;F%nQ#yyQZ>$}vp^e3A*&)es> zjNcl5hw^Kji|sW5tLD&!X7rdLrc$RC7Xu1dV9)vBwNSr=)ruMh$DZ@S>lWbD=S1%8 zjmbXgH;Dt?Ibb2Xbr@aK3zwr=QGL?G9Ex@VIi9}lqJrVxvFBQVKi7&AbI=Qi_oA86i zujddiIp8a|-!;fWsdO@PxJw$_z{zC~b%9*=0{$Q567wnMzg+Dt!6N?u<8pZoDW(Gi zQJdDqbMg3Hd(H=MS-|JGE~s;G>^UF2bpcL&PUKo$oSE<|Q3&tO)J69Npyh1A&mB<7 zW$T4bH?0@B{jNbCUcK~C7t~8H;Qygsur%U&k*odvhprdcXn)cd0WP0kqA&Kuy+6OR z_%*Id^agFWS3hEu>c=z+HbyT*Yp7X&w7t~5zbJrV=J?DdWEx@VIsX#Jy zFhZTFV~$t4{djXXDze-Al?&gis&v(7O-Tm6JF-B0VcOn2i_*TPz~JEyBE&Yf%8XUa z9K=gNTx|Ob`uA=BUc9%X(sk3f(0W96Kq_Y(DSE90gf zegNttlcpg26Y7<19hCE>DyK#^<^b?d3BVku$78*mc0>jAAs-VD_Rsm@M{$HF%crvw z5&6@lR&tYjMhz5ptC*{In$q04$uMf+C#)nFXK3q(QFfYn7<6@M5S03Gc01kEclzHzf4pF{Z{7F9d=i7qWy`o{Qw@}W*)7&p8;*;ZdhsiU{ zUM3-gpH~qqLscL10^#9=E5{>vH)oP`L{gLlJ&K?qtm>3xn_P@jJd(iJ#DW&lbS!WE z<)Whqi)A3^jt?CTBo`gC2!5==nJHX=e>@PGlQ+8}lYY+5M>i<5Q8DgcrP>Nl01?sY z%2SI@#Aj6$aKT2*h?4{pf8dwVc@Xa=>EyPdaj}7$`vk@f71g-Gc?B^oFh&R}MrfWs zWrWGm29?$7;LTt=J4vqgKcVcFm`8oV01*_2K42N|L4JqwJCUDs|AqW6<97`|w5Eqi zxa7G5CKkNS2%pXnjLWQYB4W?^;EU9B=Z&x}x|K&PKl8z71xCx2qua#Nq%V1;_=0Dp zOx0J#9_wXZoegX5gImELPg?6CK$?bN4v?Y(OI+hVW1 zRX+pjFTK4fTQ0hYBw!Isf?D@r^UKqC4HbrWmS)U3ywfWt{AP@{#w$5~7rZCY2=`GM z+qM{+qo-TU=o!3N+5Wa_?E&;Y%iH&B_5M#hO40A^`3Iik+WP&^(AKP#oFn=RU}g;r zTFuwOZ<0o!ykJE{h(l06^rAfZ4@z|f(KE@`mc|Ev@Hv5l`n*pS3`R&o z00#%9LbY{xFhXatxtXoZVmteS3#}3!)>~BmS74u1hubeuZAS`ce=pm4M%q6RK&N@Kz&tN(z%)s+>*EBa^1ZxyV{8-8VF^d0;JOyK-4 zoSkPY(yH<5>hbEDT6JxuvIPp6*_)_nPhwz1BLO?p|3PU4uV*j({6BBPm{GgU&FQtJ9U~ zsTX#B{ovE0=gB)$nGUa&V~@%n(evd98*3_iwEvE(2mYQpsXKUC zZEjAEZ&!BX9Cl^etp&c2(A%ab+7FW4ZPP0&dvF%Joh#u9U!=@-Yb>vbh84X;B&`Tvs+Xg^z7*AnRHY0nRwFjE;r-NbWsTd6 z`na&SU8PZJgxhFjm9;is=4M(7O1hERy3(jc|75Vrn&@Tbu)QoZaI*n78!

9F4we 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%0Da*0VD2R=5WBuom5 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

-r;MMNzr)46^QLkAxf)rf^#<6nm!)b$R~hv3D(8 z15hG3WXc?02p&6-j_x^y)6hito#lC%;#S~qay%~+6BCGHu)^>EjUxd6X0sZetYXG> z9q);lI04td>1Hn*E5;aIQn!6qa67EATd%@4bWg^nmVL987m79Equ(o+TgmkWpWl$A zx~DGtU9;5np2(XcCiqMEk3PRucIVtv+bTok!h#t4yD*wjAxpzZIg77G z%|23%2ET5e9r1YYCEsbi7Eets-zl1QZ)M^9JN2uJ9ad$Z z&AL!u+jJ;i!HQ3E#qArG8-o`%(2OShvJlQFYb2K)o?b6MMz|C%dPe(yp#|OovEh|A#e~^GpmUFRQ3fFL|GI zQDUf*2SN92wjTrjPZFN+m)?&vyB2sqmVe{@ur{No3)+f=@0EtTl75{X4l(vph_UCJ zvs?N{zwY;D5{Wn?IG`dpoJ5epI+j_ZMpBq91 zPj0F%TWs)h(X>jX;~HNUE71crUX?G&OggDF>VwS0S;mHkt=@e2HUH?Bvd`}rU0Nsn z`7Zig8{75GF!<`%51*^?S(}#CO}lZm&DmwMvwGipMw!RKjh9P&D+KstGId;TJe~I} zYcTz-C0y0nlbF$(qG|YH?#y`2 z1dU(PM*AeyIx8!c!*hClC#=*q!Q?7sNNqUv0ai#5sLr9$CxRkttJ3*WFnaS<*N zHCW^tROVQzYI&|+)$7Y;<%+c$(FUD5ygNO2Y`ir3*s|9$>*eottD3%MiZ2%4(O9%x z`-)GKbk5nFi2}QqE5>WmHh!Km^3*iSSYD6HLjxt*mSS~B@0?tceOGb0>e^t0=Fgre%XZlp9Xh~QG z&a^(3r|4CXwQq0gyyME#!=8k?{QBCKYtoUtab4LQ`^Km{6JMJMnomvCsJ-zaeA0|Q z8;^Z6jdz5O_OIKnx9`inpx%S`_s$WPe{yzeZ1gL0T|P$b{Fl}jAH04%XI19`_q8{7 z7VHxElrOfgdR9g3cAXpRX-PAZ_a{v=ydoKrbg`l>Vr=^NU6OUD;%_=QtbMe5_nyIL8-wbww-tvS zcN$uxmxP{Kzs{z|P4DaKU&}Q@&PN(y8&|#&q)Cdto{w!%lhgW9yY%3c)3sh|uZ6wJ cJTN83vrnF7hn%-xn78i}Z5_O9frsb+0DHWnI{*Lx literal 0 HcmV?d00001 diff --git a/Install/Program Files to Install/Revit.IFC.Export.dll b/Install/Program Files to Install/Revit.IFC.Export.dll new file mode 100644 index 0000000000000000000000000000000000000000..539f4b58c14280128c523317c72fa632d3b373d7 GIT binary patch literal 4063776 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 |frwx@5O2 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 z%0D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%0ADJt>Y_7!=cx7z$#ca9<4aBXd0|#xDYju-}pR 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 WZ#ZU9C5gPK91R*9M_Oz#woTQ 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%0Dcy852XjcUpj@x_=skF(@@7jO71p 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

4ypKttYQ?tgY9w*Ig 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

A)e}SHAw6X{N>Nj02;*3KuKC> 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 G7*?w1!;<^ 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 K?AP^DhyMU9{)d_X literal 0 HcmV?d00001 diff --git a/Install/Program Files to Install/Revit.IFC.Import.dll b/Install/Program Files to Install/Revit.IFC.Import.dll new file mode 100644 index 0000000000000000000000000000000000000000..129b4cb7b55336633f5c7161cf78f1bdae4f3ea6 GIT binary patch literal 526112 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

;hJ&MH=yq!ZmmB5a9PFz{ofUX5P^QG#!8aHu>d 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

)5)VadJ6h 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%0DO04q$zF5<$if2U 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 waum~&vXxI9C+8QlfO@O3t

@@ -81,7 +81,7 @@

Getting Started

Revit IFC

- Revit IFC 2024 contains up-to-date improvements on the default IFC capabilities of Revit contributed by Autodesk and our Open + Revit IFC 2025 contains up-to-date improvements on the default IFC capabilities of Revit contributed by Autodesk and our Open Source contributors. While this app is not necessary for IFC support, it is recommended that users that depend on the quality of their IFC download this app and keep it up-to-date, as new enhancements and defect fixes are added, For more information on IFC, please visit the buildingSMART website or the Revit wiki. @@ -236,150 +236,51 @@

Support Information

or if you have an inquiry specific to this add-in, send us an e-mail to: Revit.apps@autodesk.com

Version History

-
24.2.0.49
+
25.2.0.5

General:

    -
  • This is the major update of IFC Exporter for Revit 2024. -
  • It contains a various improvements and bug fixes for the basic Revit 2024. -
-

-
-

- Improvements: -

    -
  • Added export of the floor slab edge level. -
  • Added Width as an exported quantity to IFC for some assembly-based walls. -
  • Implemented IfcMaterialLayerSetUsage assigning to a single occurence. -
  • Improved export of sloped slabs. -
  • Improved stability when exporting projects to IFC with non-standard Author information in Project Standards. -
  • Updated French and German localization resources -
-

-
-

- Bug Fixes: -

    -
  • Fixed an unexpected error during file export. -
  • Fixed bug with inverted geometry after export of parts as ceilings. -
  • Fixed bug with swapped Height and Width values of opening in Base Quantities in exported IFC. -
  • Fixed export of NetSideArea, GrossSideArea, Height and Width to IFC4 QTO for curtain walls. -
  • Fixed geometry transformation for some cases. -
  • Fixed missing material associations for solid model bodies. -
  • Fixed openings local placement export. -
-

-
-
-
- -
24.1.1.6
-

- General: -

    -
  • This is the minor update of IFC Exporter for Revit 2024. -
  • It contains a various improvements and bug fixes for the basic Revit 2024. -
-

-
-

- Improvements: -

    -
  • The default import processor has been changed to Hybrid -
-

-
-

- Bug Fixes: -

    -
  • Fixed a bunch of potential bugs related to the compatibility with older Revit versions. -
  • Fix sketch-based openings in sloped slabs. -
  • Fixed placement of some specific wall sweep elements. -
-

-
-
-
- -
24.1.0.22
-

- General: -

    -
  • This is the first version of IFC Exporter for Revit 2024. -
  • It contains a various improvements and bug fixes for the basic Revit 2024. +
  • This is the first version of IFC Exporter for Revit 2025. +
  • It contains a various improvements and bug fixes for the basic Revit 2025.


Improvements:

    -
  • Added IFC2x3 Qto sets. -
  • Added material shared parameters export. -
  • Added the BarRole attribute when exporting IfcReinforcingBars to IFC. -
  • Added type entities for rebar and assemblies when exporting to IFC. -
  • Added support for exporting predefined types when exporting spaces to IFC4+. -
  • Added support of new measure units. -
  • Allowed export of rebar with slightly invalid transforms to IFC. -
  • Implemented exporting user defined parameters of 'Real' type as IfcReal with Revit display values. -
  • Implemented exporting of IfcRailingType entity. -
  • Implemented support of all 4 Revit velocity data types on export. -
  • Improved display of openings when export or linking in IFC files. -
  • Improved calculation of the linked levels elevation. -
  • Improved export of IfcPropertyEnumeratedValue. -
  • Improved export of insulation and lining as anything. -
  • Improved export of projects to IFC that contained family instances with invalid placements. -
  • Improved how classifications are viewed in certain older external applications when exporting to IFC. -
  • Improved list/bounded/table user defined properties values export for Instances and Types. -
  • Improved placement of federated (and some separate) links. -
  • Improved processing of representation items. -
  • Improved support for exporting advanced BReps to IFC if the unofficial IFC4 Design Transfer View is used. -
  • Improved the behavior for export of elements split by levels. -
  • Improved user defined property set mapping, especially for IFC2x3 entities that previously had no type entity exported. -
  • Updated 4x3 enums according to IFC4.3.1.0 Documentation. +
  • Added type information when exporting Rebar couplers to IFC. +
  • Allowed export of some elements to IFC4 Reference View [Structural] that had no material assignments. +
  • Allowed Revit to preserve the active site after IFC export. +
  • Allowed some old IFC configuration settings to be upgraded. +
  • Better treatment of IfcSpatialZones and zones in general. +
  • Improved base quantities calculation for spatial elements. +
  • Improved category mapping dialog. +
  • Improved error handling for invalid Revit file with missing project base and survey points. +
  • Improved export of classification data to IFC for curtain wall doors. +
  • Improved export of classification description to IFC. +
  • Improved export of IsExternal parameter, removed support at type level. +
  • Improved performance of some elongated elements export to IFC 4. +
  • Improved positioning of linked instances when exporting to IFC. +
  • Improved the color assignments for some elements exported to IFC 4. +
  • Improved the export of current view only IFC files when the phase of the view has changed since it was first set in the IFC export settings. +
  • Improved the validity of exported IFC files when exporting some planar geometry.


Bug Fixes:

    -
  • Corrected the value for many MEP parameters exported to IFC. -
  • Fixed colour for exported pipe fitting. -
  • Fixed inconsistent IfcMaterialConstituent naming. -
  • Fixed export of a user-defined structural element type. -
  • Fixed export of IfcFurnitureType.AssemblyPlace attribute. -
  • Fixed export of IFC properties associated with the top-level IfcProject entity. -
  • Fixed export of materials from hosted wall sweep. -
  • Fixed export of material layer parameters of a ceiling element. -
  • Fixed export of user defined properties for roofs. -
  • Fixed export of some assemblies to IFC that resulted in orphaned entities. -
  • Fixed export of stairs layer name. -
  • Fixed IFC Classification export. -
  • Fixed IFCMEASUREWITHUNIT. -
  • Fixed log file creation for linking. -
  • Fixed the calculation of the height parameter for some railings in metric projects when a previous value had been calculated that wasn't applicable to this railing. -
  • Fixed the issue when IfcCovering sill's body was exported as Brep instead of SweptSolid. -
  • Fixed the processing of openings when exporting a wall as shape aspects (components). -
  • Fixed the slope common property set parameter calculation when exporting some stringers to IFC. -
  • Fixed issue with IfcCountMeasure value in IFC4x3. -
  • Fixed Revit Data types export. -
  • Fixed window opening misalignment. -
  • Removed the use of several Revit built-in parameters when exporting IFC properties that have the same name but are different. +
  • Corrected placement of some families inside assemblies when exporting to IFC. +
  • Fixed bug related to the exported grids to IFC if the project base elevation was significantly far from the origin. +
  • Fixed export of GrossArea to IFC4 QTO base quantities for Revit walls exported as IfcCovering. +
  • Fixed export of some missing elements when exporting linked documents to IFC. +
  • Fixed export of walls with openings placed next to clippings. +
  • Fixed Width parameter for IfcSlab and IfcCovering exported to IFC4 QTO base quantities. +
  • Fixed wrong elevation of linked models exporting host file with links to one IFC file.



- -
-
24.0.0.0
-

- General: - -

    -
  • This is the first version of IFC Extension for Revit 2024. -
-
-
- diff --git a/Install/Program Files to Install/bundle/PackageContents.xml b/Install/Program Files to Install/bundle/PackageContents.xml index 3ec722c5..64878809 100644 --- a/Install/Program Files to Install/bundle/PackageContents.xml +++ b/Install/Program Files to Install/bundle/PackageContents.xml @@ -1,10 +1,10 @@  - + - - - - - + + + + + \ No newline at end of file diff --git a/Install/RevitIFCSetupWix/Product.wxs b/Install/RevitIFCSetupWix/Product.wxs index 32dd1740..ead8a261 100644 --- a/Install/RevitIFCSetupWix/Product.wxs +++ b/Install/RevitIFCSetupWix/Product.wxs @@ -2,7 +2,7 @@ - + @@ -19,7 +19,7 @@ - + @@ -44,7 +44,7 @@ - + @@ -55,12 +55,12 @@ - + - + @@ -73,9 +73,9 @@ - + - + @@ -117,6 +117,12 @@ + + + + + + @@ -133,14 +139,10 @@ + + + - - - - - - - @@ -154,27 +156,15 @@ - - - - - - - - - - - - diff --git a/Install/RevitIFCSetupWix/RevitIFCSetupWix.wixproj b/Install/RevitIFCSetupWix/RevitIFCSetupWix.wixproj index 4556867e..f7a1c7ce 100644 --- a/Install/RevitIFCSetupWix/RevitIFCSetupWix.wixproj +++ b/Install/RevitIFCSetupWix/RevitIFCSetupWix.wixproj @@ -6,7 +6,7 @@ 3.8 7dfbd495-c588-4c7b-b8f6-5b793adb06f2 2.0 - IFC for Revit 2024.2.0.49 + IFC for Revit 2025.2.0.5 Package $(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets $(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets diff --git a/Install/RevitIFCSetupWix/buildInstaller.bat b/Install/RevitIFCSetupWix/buildInstaller.bat index 4f114331..ac68ba99 100644 --- a/Install/RevitIFCSetupWix/buildInstaller.bat +++ b/Install/RevitIFCSetupWix/buildInstaller.bat @@ -11,9 +11,9 @@ rem It is necessary to add the Wix bin directory to the system path temporarily SET PATH=%PATH%;%WixRoot% candle.exe -dProjectDir=%2 -ext WixUtilExtension %2Product.wxs -light.exe -ext WixUtilExtension -out RevitIFC2024.2.0.msi product.wixobj -ext WixUIExtension +light.exe -ext WixUtilExtension -out RevitIFC2025.2.0.msi product.wixobj -ext WixUIExtension -copy RevitIFC2024.2.0.msi %1..\Releasex64 -del RevitIFC2024.2.0.msi +copy RevitIFC2025.2.0.msi %1..\Releasex64 +del RevitIFC2025.2.0.msi -echo %1..\Releasex64\RevitIFC2024.2.0.msi +echo %1..\Releasex64\RevitIFC2025.2.0.msi diff --git a/Revit.IFC.sln b/Revit.IFC.sln index f8d6db56..26d7a673 100644 --- a/Revit.IFC.sln +++ b/Revit.IFC.sln @@ -1,23 +1,23 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.32228.343 +# Visual Studio Version 17 +VisualStudioVersion = 17.8.34330.188 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Revit.IFC.Import", "Source\Revit.IFC.Import\Revit.IFC.Import.csproj", "{7F987D09-9716-4F50-ADE0-278E4B537101}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Revit.IFC.Import", "Source\Revit.IFC.Import\Revit.IFC.Import.csproj", "{7F987D09-9716-4F50-ADE0-278E4B537101}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Revit.IFC.Export", "Source\Revit.IFC.Export\Revit.IFC.Export.csproj", "{BCE5141A-291B-4CD8-A69B-7B9345AA00E9}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Revit.IFC.Export", "Source\Revit.IFC.Export\Revit.IFC.Export.csproj", "{BCE5141A-291B-4CD8-A69B-7B9345AA00E9}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Revit.IFC.Common", "Source\Revit.IFC.Common\Revit.IFC.Common.csproj", "{032EA4DC-181F-4453-9F93-E08DE1C07D95}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Revit.IFC.Common", "Source\Revit.IFC.Common\Revit.IFC.Common.csproj", "{032EA4DC-181F-4453-9F93-E08DE1C07D95}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IFCExporterUIOverride", "Source\IFCExporterUIOverride\IFCExporterUIOverride.csproj", "{BF694550-5BEB-4DCF-8EC2-A5904690DC17}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IFCExporterUIOverride", "Source\IFCExporterUIOverride\IFCExporterUIOverride.csproj", "{BF694550-5BEB-4DCF-8EC2-A5904690DC17}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Install", "Install", "{88C55E9A-2767-48B7-A035-E3D864C4FF09}" EndProject Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "RevitIFCSetupWix", "Install\RevitIFCSetupWix\RevitIFCSetupWix.wixproj", "{7DFBD495-C588-4C7B-B8F6-5B793ADB06F2}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RevitIFCTools", "Source\RevitIFCTools\RevitIFCTools.csproj", "{FFD592F6-DB2C-4E5D-9C38-9CCC9EABB3EA}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RevitIFCTools", "Source\RevitIFCTools\RevitIFCTools.csproj", "{FFD592F6-DB2C-4E5D-9C38-9CCC9EABB3EA}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Revit.IFC.Import.Core", "Source\Revit.IFC.Import.Core\Revit.IFC.Import.Core.csproj", "{B1E159B7-4B12-45A9-B83F-159E37798D44}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Revit.IFC.Import.Core", "Source\Revit.IFC.Import.Core\Revit.IFC.Import.Core.csproj", "{B1E159B7-4B12-45A9-B83F-159E37798D44}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/Source/IFCExporterUIOverride/IFCCategoryMapping/IFCCategoryMapping.xaml b/Source/IFCExporterUIOverride/IFCCategoryMapping/IFCCategoryMapping.xaml new file mode 100644 index 00000000..95873f57 --- /dev/null +++ b/Source/IFCExporterUIOverride/IFCCategoryMapping/IFCCategoryMapping.xaml @@ -0,0 +1,342 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + diff --git a/Source/IFCExporterUIOverride/IFCExporterUIWindow.xaml.cs b/Source/IFCExporterUIOverride/IFCExporterUIWindow.xaml.cs index 80e58e2d..a50240fe 100644 --- a/Source/IFCExporterUIOverride/IFCExporterUIWindow.xaml.cs +++ b/Source/IFCExporterUIOverride/IFCExporterUIWindow.xaml.cs @@ -21,19 +21,18 @@ using Autodesk.Revit.DB.IFC; using Autodesk.Revit.UI; using Autodesk.UI.Windows; -using Microsoft.Win32; using Revit.IFC.Common.Utility; using Revit.IFC.Export.Utility; using System; using System.IO; using System.Collections.Generic; using System.Linq; -using System.Web.Script.Serialization; using System.Windows; using System.Windows.Controls; using UserInterfaceUtility.Json; using Revit.IFC.Common.Enums; using Revit.IFC.Common.Extensions; +using Newtonsoft.Json; namespace BIM.IFC.Export.UI { @@ -186,11 +185,34 @@ private void UpdateConfigurationsList(String currentConfigName) InitializeConfigurationList(currentConfigName); } + private void InitComboBoxCategoryMapping(Document document) + { + string originalSelectedItem = (string) comboBoxCategoryMapping.SelectedItem; + comboBoxCategoryMapping.SelectedItem = null; + comboBoxCategoryMapping.Items.Clear(); + + comboBoxCategoryMapping.Items.Add(Properties.Resources.InSessionConfiguration); + + IList mappingList = IFCCategoryTemplate.ListNames(document); + if (mappingList != null) + { + foreach (string mappingName in mappingList) + { + comboBoxCategoryMapping.Items.Add(mappingName); + } + } + + comboBoxCategoryMapping.SelectedItem = originalSelectedItem != null && comboBoxCategoryMapping.Items.Contains(originalSelectedItem) ? + originalSelectedItem : Properties.Resources.InSessionConfiguration; + } + /// /// Initializes the comboboxes via the configuration options. /// private void InitializeConfigurationOptions() { + Document document = IFCExport.TheDocument; + if (!comboboxIfcType.HasItems) { comboboxIfcType.Items.Add(new IFCVersionAttributes(IFCVersion.IFC2x2)); @@ -230,7 +252,7 @@ private void InitializeConfigurationOptions() if (!comboboxActivePhase.HasItems) { - PhaseArray phaseArray = IFCCommandOverrideApplication.TheDocument.Phases; + PhaseArray phaseArray = document.Phases; comboboxActivePhase.Items.Add(new IFCPhaseAttributes(ElementId.InvalidElementId)); // Default. foreach (Phase phase in phaseArray) { @@ -249,8 +271,7 @@ private void InitializeConfigurationOptions() if (!comboBoxProjectSite.HasItems) { - Document doc = IFCExport.TheDocument; - foreach (ProjectLocation pLoc in doc.ProjectLocations.Cast().ToList()) + foreach (ProjectLocation pLoc in document.ProjectLocations.Cast().ToList()) { // There seem to be a possibility that the Site Locations can have the same name (UI does not allow it though) // In this case, it will skip the duplicate since there is no way for this to know which one is exactly selected @@ -280,13 +301,18 @@ private void InitializeConfigurationOptions() comboboxLinkedFiles.Items.Add(new IFCLinkedFileExportAs(LinkedFileExportAs.ExportSameProject)); comboboxLinkedFiles.Items.Add(new IFCLinkedFileExportAs(LinkedFileExportAs.ExportSameSite)); } + + if (!comboBoxCategoryMapping.HasItems) + { + InitComboBoxCategoryMapping(document); + } } private void UpdatePhaseAttributes(IFCExportConfiguration configuration) { if (configuration.VisibleElementsOfCurrentView) { - UIDocument uiDoc = new UIDocument(IFCCommandOverrideApplication.TheDocument); + UIDocument uiDoc = new UIDocument(IFCExport.TheDocument); Parameter currPhase = uiDoc.ActiveView.get_Parameter(BuiltInParameter.VIEW_PHASE); if (currPhase != null) configuration.ActivePhaseId = currPhase.AsElementId().Value; @@ -326,6 +352,8 @@ private void UpdateActiveConfigurationOptions(IFCExportConfiguration configurati UpdateExchangeRequirement(configuration); + UpdateFacilityType(configuration); + foreach (IFCFileFormatAttributes format in comboboxFileType.Items.Cast()) { if (configuration.IFCFileType == format.FileType) @@ -371,6 +399,9 @@ private void UpdateActiveConfigurationOptions(IFCExportConfiguration configurati } } + string categoryMapping = configuration.CategoryMapping ?? Properties.Resources.InSessionConfiguration; + comboBoxCategoryMapping.SelectedItem = categoryMapping; + UpdatePhaseAttributes(configuration); checkboxExportBaseQuantities.IsChecked = configuration.ExportBaseQuantities; @@ -409,6 +440,10 @@ private void UpdateActiveConfigurationOptions(IFCExportConfiguration configurati userDefinedParameterMappingTable.Text = configuration.ExportUserDefinedParameterMappingFileName; checkBoxExportUserDefinedParameterMapping.IsChecked = configuration.ExportUserDefinedParameterMapping; + checkbox_ExportHostAsSingleEntity.IsChecked = configuration.ExportHostAsSingleEntity; + + checkbox_OwnerHistoryLastModified.IsChecked = configuration.OwnerHistoryLastModified; + // Keep old behavior where by default we looked for ParameterMappingTable.txt in the current directory if ExportUserDefinedParameterMappingFileName // isn't set. if (string.IsNullOrWhiteSpace(configuration.ExportUserDefinedParameterMappingFileName)) @@ -454,7 +489,11 @@ private void UpdateActiveConfigurationOptions(IFCExportConfiguration configurati checkBoxExportSpecificSchedules, checkBox_TriangulationOnly, checkbox_UseTypeNameOnly, - checkbox_UseVisibleRevitNameAsEntityName + checkbox_UseVisibleRevitNameAsEntityName, + checkbox_ExportHostAsSingleEntity, + checkbox_OwnerHistoryLastModified, + comboBoxCategoryMapping, + buttonCategoryMapping }; foreach (UIElement element in configurationElements) @@ -466,7 +505,7 @@ private void UpdateActiveConfigurationOptions(IFCExportConfiguration configurati userDefinedParameterMappingTable.IsEnabled = userDefinedParameterMappingTable.IsEnabled && configuration.ExportUserDefinedParameterMapping; buttonBrowse.IsEnabled = buttonBrowse.IsEnabled && configuration.ExportUserDefinedPsets; buttonParameterMappingBrowse.IsEnabled = buttonParameterMappingBrowse.IsEnabled && configuration.ExportUserDefinedParameterMapping; - + // ExportRoomsInView option will only be enabled if it is not currently disabled AND the "export elements visible in view" option is checked bool? cboVisibleElementInCurrentView = checkboxVisibleElementsCurrView.IsChecked; checkBoxExportRoomsInView.IsEnabled = checkBoxExportRoomsInView.IsEnabled && cboVisibleElementInCurrentView.HasValue ? cboVisibleElementInCurrentView.Value : false; @@ -497,6 +536,12 @@ private void UpdateActiveConfigurationOptions(IFCExportConfiguration configurati checkbox_UseVisibleRevitNameAsEntityName.IsChecked = configuration.UseVisibleRevitNameAsEntityName; checkbox_UseVisibleRevitNameAsEntityName.IsEnabled = true; + checkbox_ExportHostAsSingleEntity.IsChecked = configuration.ExportHostAsSingleEntity; + checkbox_ExportHostAsSingleEntity.IsEnabled = true; + + checkbox_OwnerHistoryLastModified.IsChecked = configuration.OwnerHistoryLastModified; + checkbox_OwnerHistoryLastModified.IsEnabled = true; + if (configuration.IFCVersion.Equals(IFCVersion.IFC2x3FM)) { DoCOBieSpecificSetup(configuration); @@ -677,6 +722,7 @@ private void buttonDeleteSetup_Click(object sender, RoutedEventArgs e) m_configurationsMap.Remove(configuration.Name); listBoxConfigurations.Items.Remove(configuration); listBoxConfigurations.SelectedIndex = 0; + IFCExport.LastSelectedConfig.Remove(configuration.Name); } /// @@ -705,50 +751,49 @@ private void buttonSaveSetup_Click(object sender, RoutedEventArgs e) return; } - SaveFileDialog saveFileDialog = new SaveFileDialog(); - saveFileDialog.AddExtension = true; - - saveFileDialog.DefaultExt = "json"; - saveFileDialog.Filter = Properties.Resources.ConfigurationFilePrefix + " (*.json)|*.json"; - saveFileDialog.FileName = Properties.Resources.ConfigurationFilePrefix + " - " + configuration.Name + ".json"; - saveFileDialog.InitialDirectory = GetDefaultDirectory(); - saveFileDialog.OverwritePrompt = false; - - bool? fileDialogResult = saveFileDialog.ShowDialog(); - if (fileDialogResult.HasValue && fileDialogResult.Value) + FileSaveDialog fileSaveDialog = new FileSaveDialog(Properties.Resources.ConfigurationFilePrefix + " (*.json)|*.json"); + fileSaveDialog.InitialFileName = GetDefaultDirectory() + "\\" + Properties.Resources.ConfigurationFilePrefix + " - " + configuration.Name + ".json"; + + if (fileSaveDialog.Show() == ItemSelectionDialogResult.Confirmed) { - IFCExportConfiguration configToSave = configuration.Clone(); - configToSave.Name = Path.GetFileNameWithoutExtension(saveFileDialog.FileName); - using (StreamWriter sw = new StreamWriter(saveFileDialog.FileName)) + try + { + ModelPath modelPath = fileSaveDialog.GetSelectedModelPath(); + string fileName = ModelPathUtils.ConvertModelPathToUserVisiblePath(modelPath); + IFCExportConfiguration configToSave = configuration.Clone(); + configToSave.Name = Path.GetFileNameWithoutExtension(fileName); + using (StreamWriter sw = new StreamWriter(fileName)) + { + JsonSerializerSettings dateFormatSettings = new JsonSerializerSettings + { + DateFormatHandling = DateFormatHandling.MicrosoftDateFormat + }; + sw.Write(SerializerUtils.FormatOutput(JsonConvert.SerializeObject(configToSave, dateFormatSettings))); + } + } + catch { - JavaScriptSerializer js = new JavaScriptSerializer(); - sw.Write(SerializerUtils.FormatOutput(js.Serialize(configToSave))); + // TODO: Give error. } } } private void buttonLoadSetup_Click(object sender, RoutedEventArgs e) { - OpenFileDialog openFileDialog = new Microsoft.Win32.OpenFileDialog(); - - // Set filter for file extension and default file extension - openFileDialog.DefaultExt = ".json"; - openFileDialog.Filter = Properties.Resources.ConfigurationFilePrefix + " (*.json)|*.json"; - openFileDialog.InitialDirectory = GetDefaultDirectory(); + FileOpenDialog fileOpenDialog = new FileOpenDialog(Properties.Resources.ConfigurationFilePrefix + " (*.json)|*.json"); + fileOpenDialog.Title = Properties.Resources.LoadSetup; // Display OpenFileDialog by calling ShowDialog method - bool? result = openFileDialog.ShowDialog(); - - // Get the selected file name and display in a TextBox - if (result.HasValue && result.Value) + if (fileOpenDialog.Show() == ItemSelectionDialogResult.Confirmed) { + // Get the selected file name and display in a TextBox try { - using (StreamReader sr = new StreamReader(openFileDialog.FileName)) + ModelPath modelPath = fileOpenDialog.GetSelectedModelPath(); + string fileName = ModelPathUtils.ConvertModelPathToUserVisiblePath(modelPath); + + using (StreamReader sr = new StreamReader(fileName)) { - JavaScriptSerializer jsConvert = new JavaScriptSerializer(); - jsConvert.RegisterConverters(new JavaScriptConverter[] { - new IFCExportConfigurationConverter() }); - IFCExportConfiguration configuration = jsConvert.Deserialize(sr.ReadToEnd()); + IFCExportConfiguration configuration = JsonConvert.DeserializeObject(sr.ReadToEnd(), new IFCExportConfigurationConverter()); if (configuration != null) { if (m_configurationsMap.HasName(configuration.Name)) @@ -789,6 +834,8 @@ private void buttonRenameSetup_Click(object sender, RoutedEventArgs e) m_configurationsMap.Remove(oldName); m_configurationsMap.AddOrReplace(configuration); UpdateConfigurationsList(newName); + if (IFCExport.LastSelectedConfig.ContainsKey(oldName)) + IFCExport.LastSelectedConfig.Remove(oldName); } } @@ -1120,6 +1167,8 @@ private void comboboxIfcType_SelectionChanged(object sender, SelectionChangedEve } UpdateExchangeRequirement(configuration); + + UpdateFacilityType(configuration); } if (configuration.IFCVersion.Equals(IFCVersion.IFC2x3FM)) @@ -1403,7 +1452,7 @@ private void buttonBrowse_Click(object sender, RoutedEventArgs e) { IFCExportConfiguration configuration = GetSelectedConfiguration(); - OpenFileDialog dlg = new OpenFileDialog(); + Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog(); // Set filter for file extension and default file extension dlg.DefaultExt = ".txt"; @@ -1438,7 +1487,7 @@ private void buttonParameterMappingBrowse_Click(object sender, RoutedEventArgs e { IFCExportConfiguration configuration = GetSelectedConfiguration(); - OpenFileDialog dlg = new OpenFileDialog(); + Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog(); dlg.DefaultExt = ".txt"; dlg.Filter = Properties.Resources.UserDefinedParameterMappingTable + @"|*.txt"; @@ -1516,6 +1565,18 @@ private void buttonAddressInformation_Click(object sender, RoutedEventArgs e) }; addressInformationWindow.ShowDialog(); } + private void buttonCategoryMapping_Click(object sender, RoutedEventArgs e) + { + IFCCategoryMapping categoryMapping = new IFCCategoryMapping() + { + Owner = this + }; + categoryMapping.ShowDialog(); + + // Refresh the category mapping pulldown in case we deleted an option. + InitComboBoxCategoryMapping(IFCExport.TheDocument); + } + private void buttonClassification_Click(object sender, RoutedEventArgs e) { @@ -1562,6 +1623,30 @@ private void Checkbox_UseTypeNameOnly_Unchecked(object sender, RoutedEventArgs e configuration.UseTypeNameOnlyForIfcType = false; } + private void Checkbox_ExportHostAsSingleEntity_Checked(object sender, RoutedEventArgs e) + { + IFCExportConfiguration configuration = GetSelectedConfiguration(); + configuration.ExportHostAsSingleEntity = true; + } + + private void Checkbox_ExportHostAsSingleEntity_Unchecked(object sender, RoutedEventArgs e) + { + IFCExportConfiguration configuration = GetSelectedConfiguration(); + configuration.ExportHostAsSingleEntity = false; + } + + private void Checkbox_OwnerHistoryLastModified_Checked(object sender, RoutedEventArgs e) + { + IFCExportConfiguration configuration = GetSelectedConfiguration(); + configuration.OwnerHistoryLastModified = true; + } + + private void Checkbox_OwnerHistoryLastModified_Unchecked(object sender, RoutedEventArgs e) + { + IFCExportConfiguration configuration = GetSelectedConfiguration(); + configuration.OwnerHistoryLastModified = false; + } + private void Checkbox_UseVisibleRevitName_Checked(object sender, RoutedEventArgs e) { IFCExportConfiguration configuration = GetSelectedConfiguration(); @@ -1583,6 +1668,54 @@ private void comboBoxExchangeRequirement_SelectionChanged(object sender, Selecti } } + private void comboBoxFacilityType_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + if (comboBoxFacilityType.SelectedValue != null) + { + IFCExportConfiguration configuration = GetSelectedConfiguration(); + configuration.FacilityType = IFCFacilityTypes.GetFacilityEnum(comboBoxFacilityType.SelectedValue.ToString()); + UpdateFacilityPredefinedType(configuration); + } + } + + private void comboBoxFacilityPredefinedType_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + if (comboBoxFacilityPredefinedType.SelectedValue != null) + { + IFCExportConfiguration configuration = GetSelectedConfiguration(); + configuration.FacilityPredefinedType = + IFCFacilityTypes.GetFacilityPredefinedTypeEnum(configuration.FacilityType, + comboBoxFacilityPredefinedType.SelectedValue.ToString()); + } + } + + private void comboBoxCategoryMapping_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + if (comboBoxCategoryMapping.SelectedValue != null) + { + Document doc = IFCExport.TheDocument; + IFCExportConfiguration configuration = GetSelectedConfiguration(); + string categoryMappingName = (string)comboBoxCategoryMapping.SelectedItem; + + try + { + if (!string.IsNullOrWhiteSpace(categoryMappingName) && + IFCCategoryTemplate.FindByName(doc, categoryMappingName) != null) + { + configuration.CategoryMapping = categoryMappingName; + } + else + { + configuration.CategoryMapping = null; + } + } + catch + { + configuration.CategoryMapping = null; + } + } + } + private void UpdateExchangeRequirement(IFCExportConfiguration configuration) { if (IFCExchangeRequirements.ExchangeRequirements.ContainsKey(configuration.IFCVersion)) @@ -1599,6 +1732,48 @@ private void UpdateExchangeRequirement(IFCExportConfiguration configuration) comboBoxExchangeRequirement.IsEnabled = !configuration.IsBuiltIn; } + private void UpdateFacilityPredefinedType(IFCExportConfiguration configuration) + { + System.Windows.Visibility predefinedTypeVisibility = System.Windows.Visibility.Hidden; + KnownFacilityTypes facilityType = configuration.FacilityType; + if (IFCFacilityTypes.FacilityTypes.ContainsKey(configuration.IFCVersion)) + { + IList facilityPredefinedTypes = IFCFacilityTypes.FacilityPredefinedTypesForUI(facilityType); + comboBoxFacilityPredefinedType.ItemsSource = facilityPredefinedTypes; + comboBoxFacilityPredefinedType.SelectedItem = IFCFacilityTypes.ToFullLabel(facilityType, configuration.FacilityPredefinedType); + + if ((facilityPredefinedTypes?.Count ?? 0) > 0) + { + predefinedTypeVisibility = System.Windows.Visibility.Visible; + } + } + + comboBoxFacilityPredefinedType.Visibility = predefinedTypeVisibility; + labelFacilityPredefinedType.Visibility = predefinedTypeVisibility; + } + private void UpdateFacilityType(IFCExportConfiguration configuration) + { + if (IFCFacilityTypes.FacilityTypes.ContainsKey(configuration.IFCVersion)) + { + comboBoxFacilityType.ItemsSource = IFCFacilityTypes.FacilityTypesForUI(configuration.IFCVersion); + comboBoxFacilityType.SelectedItem = configuration.FacilityType.ToFullLabel(); + + comboBoxFacilityType.Visibility = System.Windows.Visibility.Visible; + labelFacilityType.Visibility = System.Windows.Visibility.Visible; + } + else + { + comboBoxFacilityType.ItemsSource = null; + comboBoxFacilityType.SelectedItem = null; + + comboBoxFacilityType.Visibility = System.Windows.Visibility.Hidden; + labelFacilityType.Visibility = System.Windows.Visibility.Hidden; + } + + UpdateFacilityPredefinedType(configuration); + comboBoxFacilityType.IsEnabled = true; + } + private void TextBox_EPSG_TextChanged(object sender, TextChangedEventArgs e) { } @@ -1726,7 +1901,9 @@ private void button_ExcludeElement_Click(object sender, RoutedEventArgs e) { IFCExportConfiguration configuration = GetSelectedConfiguration(); string desc = ""; - EntityTree entityTree = new EntityTree(configuration.IFCVersion, configuration.ExcludeFilter, desc, singleNodeSelection: false) + + EntityTree entityTree = new EntityTree(configuration.IFCVersion, + configuration.ExcludeFilter, desc, false) { Owner = this, Title = Properties.Resources.IFCEntitySelection diff --git a/Source/IFCExporterUIOverride/IFCFacilityTypes.cs b/Source/IFCExporterUIOverride/IFCFacilityTypes.cs new file mode 100644 index 00000000..530617ef --- /dev/null +++ b/Source/IFCExporterUIOverride/IFCFacilityTypes.cs @@ -0,0 +1,321 @@ +// +// BIM IFC export alternate UI library: this library works with Autodesk(R) Revit(R) to provide an alternate user interface for the export of IFC files from Revit. +// Copyright (C) 2016 Autodesk, Inc. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +using System; +using System.Collections.Generic; +using System.Linq; +using Autodesk.Revit.DB; +using BIM.IFC.Export.UI.Properties; +using Revit.IFC.Common.Enums; +using Revit.IFC.Export.Toolkit.IFC4x3; + +namespace BIM.IFC.Export.UI +{ + class IFCFacilityTypes + { + /// + /// The list of known facility types + /// + static IDictionary> KnownFacilityTypesByVersion = new Dictionary>(); + static IDictionary> KnownFacilityTypesLocalized = new Dictionary>(); + + static IDictionary> KnownFacilityPredefinedTypesLocalized = new Dictionary>(); + + static void Initialize() + { + if (KnownFacilityTypesByVersion.Count != 0) + return; + + // For IFC4.3 + const IFCVersion ifcVersion = IFCVersion.IFC4x3; + KnownFacilityTypesByVersion.Add(ifcVersion, + new List() + { + KnownFacilityTypes.Bridge, + KnownFacilityTypes.Building, + KnownFacilityTypes.MarineFacility, + KnownFacilityTypes.Railway, + KnownFacilityTypes.Road + } + ); + + IList facilityTypeNameListForUI = + new List(KnownFacilityTypesByVersion[ifcVersion].Select(x => x.ToFullLabel())); + KnownFacilityTypesLocalized.Add(ifcVersion, facilityTypeNameListForUI); + + IList bridgePredefinedTypesForUI = new List(); + foreach (IFCBridgeType type in Enum.GetValues(typeof(IFCBridgeType))) + { + bridgePredefinedTypesForUI.Add(type.ToFullLabel()); + } + KnownFacilityPredefinedTypesLocalized[KnownFacilityTypes.Bridge] = bridgePredefinedTypesForUI; + + IList marineFacilityPredefinedTypesForUI = new List(); + foreach (IFCMarineFacilityType type in Enum.GetValues(typeof(IFCMarineFacilityType))) + { + marineFacilityPredefinedTypesForUI.Add(type.ToFullLabel()); + } + KnownFacilityPredefinedTypesLocalized[KnownFacilityTypes.MarineFacility] = marineFacilityPredefinedTypesForUI; + } + + /// + /// Get the list of known facility types. + /// + public static IDictionary> FacilityTypes + { + get + { + Initialize(); + return KnownFacilityTypesByVersion; + } + } + + /// + /// Get the list of facility types for UI based on the given IFC Version. + /// + /// The IFC Version. + /// The list of known facility types. + public static IList FacilityTypesForUI(IFCVersion ifcVers) + { + Initialize(); + return KnownFacilityTypesLocalized.FirstOrDefault(x => x.Key == ifcVers).Value; + } + + /// + /// Get the list of facility predefined types for UI based on the given facility type. + /// + /// The facility type. + /// The list of known facility predefined types. + public static IList FacilityPredefinedTypesForUI(KnownFacilityTypes facilityType) + { + Initialize(); + return KnownFacilityPredefinedTypesLocalized.FirstOrDefault(x => x.Key == facilityType).Value; + } + + /// + /// Get the enumeration value of the facility type given the localized string from the UI + /// + /// the string value from the UI + /// The facility type enumeration + public static KnownFacilityTypes GetFacilityEnum(string uiFacilityTypeStringValue) + { + KnownFacilityTypes facilityType = KnownFacilityTypes.NotDefined; + + if (Resources.FacilityBuilding.Equals(uiFacilityTypeStringValue)) + facilityType = KnownFacilityTypes.Building; + else if (Resources.FacilityBridge.Equals(uiFacilityTypeStringValue)) + facilityType = KnownFacilityTypes.Bridge; + else if (Resources.FacilityMarineFacility.Equals(uiFacilityTypeStringValue)) + facilityType = KnownFacilityTypes.MarineFacility; + else if (Resources.FacilityRoad.Equals(uiFacilityTypeStringValue)) + facilityType = KnownFacilityTypes.Road; + else if (Resources.FacilityRailway.Equals(uiFacilityTypeStringValue)) + facilityType = KnownFacilityTypes.Railway; + + return facilityType; + } + + /// + /// Get the enumeration value of the bridge type given the localized string from the UI + /// + /// the string value from the UI + /// The bridge type enumeration + private static IFCBridgeType GetBridgePredefinedTypeEnum(string uiBridgeTypeStringValue) + { + IFCBridgeType bridgeTypeEnum = IFCBridgeType.NOTDEFINED; + + if (Resources.BridgeArched.Equals(uiBridgeTypeStringValue)) + bridgeTypeEnum = IFCBridgeType.ARCHED; + else if (Resources.BridgeCableStayed.Equals(uiBridgeTypeStringValue)) + bridgeTypeEnum = IFCBridgeType.CABLE_STAYED; + else if (Resources.BridgeCantilever.Equals(uiBridgeTypeStringValue)) + bridgeTypeEnum = IFCBridgeType.CANTILEVER; + else if (Resources.BridgeCulvert.Equals(uiBridgeTypeStringValue)) + bridgeTypeEnum = IFCBridgeType.CULVERT; + else if (Resources.BridgeFramework.Equals(uiBridgeTypeStringValue)) + bridgeTypeEnum = IFCBridgeType.FRAMEWORK; + else if (Resources.BridgeGirder.Equals(uiBridgeTypeStringValue)) + bridgeTypeEnum = IFCBridgeType.GIRDER; + else if (Resources.BridgeSuspension.Equals(uiBridgeTypeStringValue)) + bridgeTypeEnum = IFCBridgeType.SUSPENSION; + else if (Resources.BridgeTruss.Equals(uiBridgeTypeStringValue)) + bridgeTypeEnum = IFCBridgeType.TRUSS; + else if (Resources.UserDefined.Equals(uiBridgeTypeStringValue)) + bridgeTypeEnum = IFCBridgeType.USERDEFINED; + + return bridgeTypeEnum; + } + + /// + /// Get the enumeration value of the marine facility type given the localized string from the UI + /// + /// the string value from the UI + /// The bridge type enumeration + private static IFCMarineFacilityType GetMarineFacilityPredefinedTypeEnum(string uiMarineFacilityTypeStringValue) + { + IFCMarineFacilityType marineFacilityTypeEnum = IFCMarineFacilityType.NOTDEFINED; + + if (Resources.MarineFacilityBarrierBeach.Equals(uiMarineFacilityTypeStringValue)) + marineFacilityTypeEnum = IFCMarineFacilityType.BARRIERBEACH; + else if (Resources.MarineFacilityBreakwater.Equals(uiMarineFacilityTypeStringValue)) + marineFacilityTypeEnum = IFCMarineFacilityType.BREAKWATER; + else if (Resources.MarineFacilityCanal.Equals(uiMarineFacilityTypeStringValue)) + marineFacilityTypeEnum = IFCMarineFacilityType.CANAL; + else if (Resources.MarineFacilityDryDock.Equals(uiMarineFacilityTypeStringValue)) + marineFacilityTypeEnum = IFCMarineFacilityType.DRYDOCK; + else if (Resources.MarineFacilityFloatingDock.Equals(uiMarineFacilityTypeStringValue)) + marineFacilityTypeEnum = IFCMarineFacilityType.FLOATINGDOCK; + else if (Resources.MarineFacilityHydrolift.Equals(uiMarineFacilityTypeStringValue)) + marineFacilityTypeEnum = IFCMarineFacilityType.HYDROLIFT; + else if (Resources.MarineFacilityJetty.Equals(uiMarineFacilityTypeStringValue)) + marineFacilityTypeEnum = IFCMarineFacilityType.JETTY; + else if (Resources.MarineFacilityLaunchRecovery.Equals(uiMarineFacilityTypeStringValue)) + marineFacilityTypeEnum = IFCMarineFacilityType.LAUNCHRECOVERY; + else if (Resources.MarineFacilityMarineDefense.Equals(uiMarineFacilityTypeStringValue)) + marineFacilityTypeEnum = IFCMarineFacilityType.MARINEDEFENCE; + else if (Resources.MarineFacilityNavigationalChannel.Equals(uiMarineFacilityTypeStringValue)) + marineFacilityTypeEnum = IFCMarineFacilityType.NAVIGATIONALCHANNEL; + else if (Resources.MarineFacilityPort.Equals(uiMarineFacilityTypeStringValue)) + marineFacilityTypeEnum = IFCMarineFacilityType.PORT; + else if (Resources.MarineFacilityQuay.Equals(uiMarineFacilityTypeStringValue)) + marineFacilityTypeEnum = IFCMarineFacilityType.QUAY; + else if (Resources.MarineFacilityRevetment.Equals(uiMarineFacilityTypeStringValue)) + marineFacilityTypeEnum = IFCMarineFacilityType.REVETMENT; + else if (Resources.MarineFacilityShipLift.Equals(uiMarineFacilityTypeStringValue)) + marineFacilityTypeEnum = IFCMarineFacilityType.SHIPLIFT; + else if (Resources.MarineFacilityShipLock.Equals(uiMarineFacilityTypeStringValue)) + marineFacilityTypeEnum = IFCMarineFacilityType.SHIPLOCK; + else if (Resources.MarineFacilityShipyard.Equals(uiMarineFacilityTypeStringValue)) + marineFacilityTypeEnum = IFCMarineFacilityType.SHIPYARD; + else if (Resources.MarineFacilitySlipway.Equals(uiMarineFacilityTypeStringValue)) + marineFacilityTypeEnum = IFCMarineFacilityType.SLIPWAY; + else if (Resources.UserDefined.Equals(uiMarineFacilityTypeStringValue)) + marineFacilityTypeEnum = IFCMarineFacilityType.USERDEFINED; + else if (Resources.MarineFacilityWaterway.Equals(uiMarineFacilityTypeStringValue)) + marineFacilityTypeEnum = IFCMarineFacilityType.WATERWAY; + else if (Resources.MarineFacilityWaterwayShiplift.Equals(uiMarineFacilityTypeStringValue)) + marineFacilityTypeEnum = IFCMarineFacilityType.WATERWAYSHIPLIFT; + + return marineFacilityTypeEnum; + } + + /// + /// Get the enumeration value of the facility predefined type given the localized string from the UI + /// + /// the string value from the UI + /// the facility predefined type enumeration + public static Enum GetFacilityPredefinedTypeEnum(KnownFacilityTypes facilityType, string uiFacilityPredefinedTypeStringValue) + { + switch (facilityType) + { + case KnownFacilityTypes.Bridge: + return GetBridgePredefinedTypeEnum(uiFacilityPredefinedTypeStringValue); + case KnownFacilityTypes.MarineFacility: + return GetMarineFacilityPredefinedTypeEnum(uiFacilityPredefinedTypeStringValue); + } + + return null; + } + + /// + /// Parse the Facility Type name string into the associated Enum + /// + /// The Facility Type Name + /// The FacilityType enum + public static KnownFacilityTypes ParseFacilityTypeEnum(string erName) + { + if (Enum.TryParse(erName, out KnownFacilityTypes erEnum)) + { + return erEnum; + } + + return KnownFacilityTypes.NotDefined; + } + + /// + /// Parse the Facility Predefined Type name string into the associated Enum + /// + /// The Facility Type + /// The Facility Predefined Type Name + /// The FacilityPredefinedType enum + public static Enum ParseFacilityPredefinedTypeEnum(KnownFacilityTypes facilityTypes, string fptName) + { + switch (facilityTypes) + { + case KnownFacilityTypes.Bridge: + { + if (Enum.TryParse(fptName, out IFCBridgeType bridgeType)) + { + return bridgeType; + } + break; + } + case KnownFacilityTypes.MarineFacility: + { + if (Enum.TryParse(fptName, out IFCMarineFacilityType marineFacilityType)) + { + return marineFacilityType; + } + break; + } + } + + return null; + } + + /// + /// Return the validated enum value for a facility type. + /// + /// The facility type. + /// The unvalidated enum. + /// The enum if valid, or null if invalid. + public static Enum ValidatedPredefinedTypeEnum(KnownFacilityTypes facilityType, Enum facilityPredefinedTypeEnum) + { + if (facilityPredefinedTypeEnum == null) + return null; + + switch (facilityType) + { + case KnownFacilityTypes.Bridge: + return facilityPredefinedTypeEnum.GetType() == typeof(IFCBridgeType) ? + facilityPredefinedTypeEnum : null; + case KnownFacilityTypes.MarineFacility: + return facilityPredefinedTypeEnum.GetType() == typeof(IFCMarineFacilityType) ? + facilityPredefinedTypeEnum : null; + } + return null; + } + + public static string ToFullLabel(KnownFacilityTypes facilityType, Enum facility) + { + Enum validatedEnum = ValidatedPredefinedTypeEnum(facilityType, facility); + if (validatedEnum == null) + return null; + + switch (facilityType) + { + case KnownFacilityTypes.Bridge: + return ((IFCBridgeType)validatedEnum).ToFullLabel(); + case KnownFacilityTypes.MarineFacility: + return ((IFCMarineFacilityType)validatedEnum).ToFullLabel(); + } + + return null; + } + } +} diff --git a/Source/IFCExporterUIOverride/IFCPhaseAttributes.cs b/Source/IFCExporterUIOverride/IFCPhaseAttributes.cs index 7f30b2ed..08c8f392 100644 --- a/Source/IFCExporterUIOverride/IFCPhaseAttributes.cs +++ b/Source/IFCExporterUIOverride/IFCPhaseAttributes.cs @@ -61,7 +61,7 @@ static public bool Validate(long phaseId) return false; Element checkPhase = IFCCommandOverrideApplication.TheDocument.GetElement(checkPhaseId); - return (checkPhase != null && (checkPhase is Phase)); + return checkPhase is Phase; } /// diff --git a/Source/IFCExporterUIOverride/IFCRenameExportSetup.xaml b/Source/IFCExporterUIOverride/IFCRenameExportSetup.xaml index 7822b4a2..e3635f00 100644 --- a/Source/IFCExporterUIOverride/IFCRenameExportSetup.xaml +++ b/Source/IFCExporterUIOverride/IFCRenameExportSetup.xaml @@ -9,7 +9,7 @@ private string m_purpose = null; - [ScriptIgnore] + [JsonIgnore] public string Purpose { get { return m_purpose; } @@ -50,7 +50,7 @@ public string Purpose /// The description of the address. /// private string m_description = null; - [ScriptIgnore] + [JsonIgnore] public string Description { get { return m_description; } @@ -67,7 +67,7 @@ public string Description /// The user defined purpose of the address. /// private string m_userDefinedPurpose = null; - [ScriptIgnore] + [JsonIgnore] public string UserDefinedPurpose { get { return m_userDefinedPurpose; } @@ -83,7 +83,7 @@ public string UserDefinedPurpose /// The internal location of the address. /// private string m_internalLocation = null; - [ScriptIgnore] + [JsonIgnore] public string InternalLocation { get { return m_internalLocation; } @@ -99,7 +99,7 @@ public string InternalLocation /// First line for the address. /// private string m_addressLine1 = string.Empty; - [ScriptIgnore] + [JsonIgnore] public string AddressLine1 { get { return m_addressLine1; } @@ -115,7 +115,7 @@ public string AddressLine1 /// Second line for the address. We limit to just 2 line addresses typically done in many applications. /// private string m_addressLine2 = string.Empty; - [ScriptIgnore] + [JsonIgnore] public string AddressLine2 { get { return m_addressLine2; } @@ -131,7 +131,7 @@ public string AddressLine2 /// PO Box address /// private string m_pOBox = null; - [ScriptIgnore] + [JsonIgnore] public string POBox { get { return m_pOBox; } @@ -147,7 +147,7 @@ public string POBox /// The city of the address. /// private string m_townOrCity = null; - [ScriptIgnore] + [JsonIgnore] public string TownOrCity { get { return m_townOrCity; } @@ -163,7 +163,7 @@ public string TownOrCity /// Region, province or state of the address. /// private string m_regionOrState = null; - [ScriptIgnore] + [JsonIgnore] public string RegionOrState { get { return m_regionOrState; } @@ -179,7 +179,7 @@ public string RegionOrState /// The postal code or zip code of the address /// private string m_postalCode = null; - [ScriptIgnore] + [JsonIgnore] public string PostalCode { get { return m_postalCode; } @@ -195,7 +195,7 @@ public string PostalCode /// The country of the address. /// private string m_country = null; - [ScriptIgnore] + [JsonIgnore] public string Country { get { return m_country; } diff --git a/Source/Revit.IFC.Common/Extension/IFCClassification.cs b/Source/Revit.IFC.Common/Extension/IFCClassification.cs index 4e767c9f..a03373b8 100644 --- a/Source/Revit.IFC.Common/Extension/IFCClassification.cs +++ b/Source/Revit.IFC.Common/Extension/IFCClassification.cs @@ -21,7 +21,7 @@ using System.Linq; using System.Text; using System.ComponentModel; -using System.Web.Script.Serialization; +using Newtonsoft.Json; namespace Revit.IFC.Common.Extensions { @@ -83,7 +83,7 @@ public DateTime ClassificationEditionDate get { return classificationEditionDate; } set { - classificationEditionDate = value.Date; + classificationEditionDate = new DateTime(value.Ticks, DateTimeKind.Utc); // Call OnPropertyChanged whenever the property is updated OnPropertyChanged("datePicker1"); } @@ -123,7 +123,7 @@ public string ClassificationFieldName /// This property is only used for the UI message. It will not be stored in the schema /// private string classificationTabMsg; - [ScriptIgnore] + [JsonIgnore] public string ClassificationTabMsg { get { return classificationTabMsg; } diff --git a/Source/Revit.IFC.Common/Extension/IFCFileHeader.cs b/Source/Revit.IFC.Common/Extension/IFCFileHeader.cs index 6a6b152b..66134ceb 100644 --- a/Source/Revit.IFC.Common/Extension/IFCFileHeader.cs +++ b/Source/Revit.IFC.Common/Extension/IFCFileHeader.cs @@ -149,27 +149,34 @@ public bool GetSavedFileHeader(Document document, out IFCFileHeaderItem fileHead if (fileHeaderStorage.Count == 0) return false; - // expected only one File Header information in the storage - Entity savedFileHeader = fileHeaderStorage[0].GetEntity(m_schema); - IDictionary savedFileHeaderMap = savedFileHeader.Get>(s_FileHeaderMapField); - if (savedFileHeaderMap.ContainsKey(s_FileDescription)) - fileHeader.FileDescriptions = savedFileHeaderMap[s_FileDescription].Split('|').ToList(); - if (savedFileHeaderMap.ContainsKey(s_SourceFileName)) - fileHeader.SourceFileName = savedFileHeaderMap[s_SourceFileName]; - if (savedFileHeaderMap.ContainsKey(s_AuthorName)) - fileHeader.AuthorName = savedFileHeaderMap[s_AuthorName]; - if (savedFileHeaderMap.ContainsKey(s_AuthorEmail)) - fileHeader.AuthorEmail = savedFileHeaderMap[s_AuthorEmail]; - if (savedFileHeaderMap.ContainsKey(s_Organization)) - fileHeader.Organization = savedFileHeaderMap[s_Organization]; - if (savedFileHeaderMap.ContainsKey(s_Authorization)) - fileHeader.Authorization = savedFileHeaderMap[s_Authorization]; - if (savedFileHeaderMap.ContainsKey(s_ApplicationName)) - fileHeader.ApplicationName = savedFileHeaderMap[s_ApplicationName]; - if (savedFileHeaderMap.ContainsKey(s_VersionNumber)) - fileHeader.VersionNumber = savedFileHeaderMap[s_VersionNumber]; - if (savedFileHeaderMap.ContainsKey(s_FileSchema)) - fileHeader.FileSchema = savedFileHeaderMap[s_FileSchema]; + try + { + // expected only one File Header information in the storage + Entity savedFileHeader = fileHeaderStorage[0].GetEntity(m_schema); + IDictionary savedFileHeaderMap = savedFileHeader.Get>(s_FileHeaderMapField); + if (savedFileHeaderMap.ContainsKey(s_FileDescription)) + fileHeader.FileDescriptions = savedFileHeaderMap[s_FileDescription].Split('|').ToList(); + if (savedFileHeaderMap.ContainsKey(s_SourceFileName)) + fileHeader.SourceFileName = savedFileHeaderMap[s_SourceFileName]; + if (savedFileHeaderMap.ContainsKey(s_AuthorName)) + fileHeader.AuthorName = savedFileHeaderMap[s_AuthorName]; + if (savedFileHeaderMap.ContainsKey(s_AuthorEmail)) + fileHeader.AuthorEmail = savedFileHeaderMap[s_AuthorEmail]; + if (savedFileHeaderMap.ContainsKey(s_Organization)) + fileHeader.Organization = savedFileHeaderMap[s_Organization]; + if (savedFileHeaderMap.ContainsKey(s_Authorization)) + fileHeader.Authorization = savedFileHeaderMap[s_Authorization]; + if (savedFileHeaderMap.ContainsKey(s_ApplicationName)) + fileHeader.ApplicationName = savedFileHeaderMap[s_ApplicationName]; + if (savedFileHeaderMap.ContainsKey(s_VersionNumber)) + fileHeader.VersionNumber = savedFileHeaderMap[s_VersionNumber]; + if (savedFileHeaderMap.ContainsKey(s_FileSchema)) + fileHeader.FileSchema = savedFileHeaderMap[s_FileSchema]; + } + catch (Exception) + { + document.Application.WriteJournalComment("IFC error: Cannot read IFCFileHeader schema", true); + } return true; } diff --git a/Source/Revit.IFC.Common/Properties/AssemblyInfo.cs b/Source/Revit.IFC.Common/Properties/AssemblyInfo.cs index 3b7c3cfb..843c920e 100644 --- a/Source/Revit.IFC.Common/Properties/AssemblyInfo.cs +++ b/Source/Revit.IFC.Common/Properties/AssemblyInfo.cs @@ -1,4 +1,3 @@ -#if IFC_OPENSOURCE using System.Reflection; // General Information about an assembly is controlled through the following @@ -7,15 +6,14 @@ [assembly: AssemblyTitle("IFC Common for Revit")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Autodesk")] +[assembly: AssemblyCompany("Autodesk, Inc.")] [assembly: AssemblyProduct("IFC Import/Exporter for Revit")] -[assembly: AssemblyCopyright("© 2012-2023 Autodesk, Inc.All rights reserved.")] +[assembly: AssemblyCopyright("© 2012-2024 Autodesk, Inc.All rights reserved.")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -[assembly: AssemblyVersion("24.2.0.49")] -[assembly: AssemblyFileVersion("24.2.0.49")] -#endif +[assembly: AssemblyVersion("25.2.0.5")] +[assembly: AssemblyFileVersion("25.2.0.5")] // Version information can now be found in Source\Foundation\RevitENU\Version.cs diff --git a/Source/Revit.IFC.Common/Revit.IFC.Common.csproj b/Source/Revit.IFC.Common/Revit.IFC.Common.csproj index 4a4ad893..016a0670 100644 --- a/Source/Revit.IFC.Common/Revit.IFC.Common.csproj +++ b/Source/Revit.IFC.Common/Revit.IFC.Common.csproj @@ -1,126 +1,26 @@ - - + - Debug - x86 - 8.0.30703 - 2.0 - {032EA4DC-181F-4453-9F93-E08DE1C07D95} - Library - Properties Revit.IFC.Common Revit.IFC.Common - v4.8 - - - 512 - {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - 4 - Publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true - Revit.IFC - - - - - - false - x64 - bin\Debugx64\ - - - false - bin\Releasex64\ - x64 + + + + + - - ..\..\..\..\Program Files\Autodesk\Revit 2024\RevitAPI.dll - - - ..\..\..\..\Program Files\Autodesk\Revit 2024\RevitAPIIFC.dll - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - False - .NET Framework 2.0 %28x86%29 - false - - - False - .NET Framework 3.0 %28x86%29 - true - - - False - .NET Framework 3.5 - false - - - False - Windows Installer 3.1 - true - + + ..\..\..\..\Program Files\Autodesk\Revit 2025\RevitAPI.dll + + + ..\..\..\..\Program Files\Autodesk\Revit 2025\RevitAPIIFC.dll + - - - xcopy "$(TargetPath)" "C:\ProgramData\Autodesk\ApplicationPlugins\IFC 2024.bundle\Contents\2024\" /F /R /Y /I - - \ No newline at end of file diff --git a/Source/Revit.IFC.Common/Revit.IFC.Common.props b/Source/Revit.IFC.Common/Revit.IFC.Common.props deleted file mode 100644 index 0e84fc8e..00000000 --- a/Source/Revit.IFC.Common/Revit.IFC.Common.props +++ /dev/null @@ -1,25 +0,0 @@ - - - - bin\Debugx64\ - DEBUG;TRACE;IFC_OPENSOURCE - true - false - false - 4 - full - prompt - - - bin\Releasex64\ - TRACE;IFC_OPENSOURCE - false - true - false - 4 - none - prompt - - - - diff --git a/Source/Revit.IFC.Export/Utility/AllocatedGeometryObjectCache.cs b/Source/Revit.IFC.Common/Utility/AllocatedGeometryObjectCache.cs similarity index 86% rename from Source/Revit.IFC.Export/Utility/AllocatedGeometryObjectCache.cs rename to Source/Revit.IFC.Common/Utility/AllocatedGeometryObjectCache.cs index a4a6fb32..d746e987 100644 --- a/Source/Revit.IFC.Export/Utility/AllocatedGeometryObjectCache.cs +++ b/Source/Revit.IFC.Common/Utility/AllocatedGeometryObjectCache.cs @@ -1,58 +1,60 @@ -// -// BIM IFC library: this library works with Autodesk(R) Revit(R) to export IFC files containing model geometry. -// Copyright (C) 2012 Autodesk, Inc. -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -using Autodesk.Revit.DB; - -namespace Revit.IFC.Export.Utility -{ - /// - /// This class aggregates all allocated geometry objects so that they can be disposed of before returning from the IFC export. - /// Although the garbage collector would eventually catch up and dispose of these objects on its own, doing it preemptively is - /// necessary in order to avoid debug errors triggered by Revit when running automated tests. - /// - public class AllocatedGeometryObjectCache - { - private List m_geometryObjects = new List(); - - /// - /// Adds a new object to the cache. - /// - /// The object. - public void AddGeometryObject(GeometryObject geometryObject) - { - m_geometryObjects.Add(geometryObject); - } - - /// - /// Executes Dispose for all geometry objects contained in the cache. - /// - public void DisposeCache() - { - foreach (GeometryObject geometryObject in m_geometryObjects) - { - geometryObject.Dispose(); - } - } - } +// +// BIM IFC library: this library works with Autodesk(R) Revit(R) to export IFC files containing model geometry. +// Copyright (C) 2012 Autodesk, Inc. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Autodesk.Revit.DB; + +namespace Revit.IFC.Common.Utility +{ + /// + /// This class aggregates all allocated geometry objects so that they can be disposed of before returning from the IFC export. + /// Although the garbage collector would eventually catch up and dispose of these objects on its own, doing it preemptively is + /// necessary in order to avoid debug errors triggered by Revit when running automated tests. + /// + public class AllocatedGeometryObjectCache + { + private List GeometryObjects { get; set; } = new List(); + + /// + /// Adds a new object to the cache. + /// + /// The object. + public void AddGeometryObject(GeometryObject geometryObject) + { + GeometryObjects.Add(geometryObject); + } + + /// + /// Executes Dispose for all geometry objects contained in the cache. + /// + public void DisposeCache() + { + foreach (GeometryObject geometryObject in GeometryObjects) + { + geometryObject.Dispose(); + } + + GeometryObjects.Clear(); + } + } } \ No newline at end of file diff --git a/Source/Revit.IFC.Common/Utility/COBieCompanyInfo.cs b/Source/Revit.IFC.Common/Utility/COBieCompanyInfo.cs index bcbc9580..66160935 100644 --- a/Source/Revit.IFC.Common/Utility/COBieCompanyInfo.cs +++ b/Source/Revit.IFC.Common/Utility/COBieCompanyInfo.cs @@ -4,7 +4,7 @@ using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; -using System.Web.Script.Serialization; +using Newtonsoft.Json; namespace Revit.IFC.Common.Utility { @@ -29,8 +29,7 @@ public COBieCompanyInfo(string compInfoStr) { if (!string.IsNullOrEmpty(compInfoStr)) { - JavaScriptSerializer js = new JavaScriptSerializer(); - COBieCompanyInfo compInfo = js.Deserialize(compInfoStr); + COBieCompanyInfo compInfo = JsonConvert.DeserializeObject(compInfoStr); CompanyType = compInfo.CompanyType; CompanyName = compInfo.CompanyName; StreetAddress = compInfo.StreetAddress; @@ -63,8 +62,7 @@ public bool PhoneValidator() public string ToJsonString() { - JavaScriptSerializer js = new JavaScriptSerializer(); - return js.Serialize(this); + return JsonConvert.SerializeObject(this); } } } \ No newline at end of file diff --git a/Source/Revit.IFC.Common/Utility/COBieProjectInfo.cs b/Source/Revit.IFC.Common/Utility/COBieProjectInfo.cs index b8624be0..58b8e367 100644 --- a/Source/Revit.IFC.Common/Utility/COBieProjectInfo.cs +++ b/Source/Revit.IFC.Common/Utility/COBieProjectInfo.cs @@ -3,7 +3,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -using System.Web.Script.Serialization; +using Newtonsoft.Json; namespace Revit.IFC.Common.Utility { @@ -27,8 +27,7 @@ public COBieProjectInfo(string projInfoStr) { if (!string.IsNullOrEmpty(projInfoStr)) { - JavaScriptSerializer js = new JavaScriptSerializer(); - COBieProjectInfo projInfo = js.Deserialize(projInfoStr); + COBieProjectInfo projInfo = JsonConvert.DeserializeObject(projInfoStr); BuildingName_Number = projInfo.BuildingName_Number; BuildingType = projInfo.BuildingType; BuildingDescription = projInfo.BuildingDescription; @@ -42,8 +41,7 @@ public COBieProjectInfo(string projInfoStr) public string ToJsonString() { - JavaScriptSerializer js = new JavaScriptSerializer(); - return js.Serialize(this); + return JsonConvert.SerializeObject(this); } } } \ No newline at end of file diff --git a/Source/Revit.IFC.Common/Utility/IFCAnyHandleUtil.cs b/Source/Revit.IFC.Common/Utility/IFCAnyHandleUtil.cs index 629facd0..11f30b2c 100644 --- a/Source/Revit.IFC.Common/Utility/IFCAnyHandleUtil.cs +++ b/Source/Revit.IFC.Common/Utility/IFCAnyHandleUtil.cs @@ -24,9 +24,70 @@ using Autodesk.Revit.DB.IFC; using Autodesk.Revit.DB; using Revit.IFC.Common.Enums; +using Autodesk.Revit.DB.Visual; namespace Revit.IFC.Common.Utility { + public static class ListExtensions + { + /// + /// Add an IFCAnyHandle to a list if the handle is valid. + /// + /// + /// The list. + /// The handle to conditionally add. + /// True if an item was added, false if not. + public static bool AddIfNotNull(this IList myList, T hnd) where T : IFCAnyHandle + { + if (IFCAnyHandleUtil.IsNullOrHasNoValue(hnd)) + return false; + + myList.Add(hnd); + return true; + } + } + + /// + /// Class containing convenience function for IDictionary of IFCAnyHandle. + /// + public static class DictionaryExtensionsClass + { + public static bool AddIfNotNullAndNewKey(this IDictionary myDictionary, + string key, T hnd) where T : IFCAnyHandle + { + if (IFCAnyHandleUtil.IsNullOrHasNoValue(hnd)) + return false; + + if (myDictionary.ContainsKey(key)) + return false; + + myDictionary[key] = hnd; + return true; + } + } + + /// + /// Class containing convenience function for ISet of IFCAnyHandle. + /// + public static class SetExtensions + { + /// + /// Add an IFCAnyHandle to a set if the handle is valid. + /// + /// + /// The set. + /// The handle to conditionally add. + /// True if an item was added, false if not. + public static bool AddIfNotNull(this ISet mySet, T hnd) where T : IFCAnyHandle + { + if (IFCAnyHandleUtil.IsNullOrHasNoValue(hnd)) + return false; + + mySet.Add(hnd); + return true; + } + } + public class IFCLimits { /// diff --git a/Source/Revit.IFC.Common/Utility/IfcSchemaEntityTree.cs b/Source/Revit.IFC.Common/Utility/IfcSchemaEntityTree.cs index 715efc90..2789a664 100644 --- a/Source/Revit.IFC.Common/Utility/IfcSchemaEntityTree.cs +++ b/Source/Revit.IFC.Common/Utility/IfcSchemaEntityTree.cs @@ -189,16 +189,22 @@ public string DumpTree() static IDictionary> DeprecatedOrUnsupportedDict = new Dictionary>() { - { Ifc4Schema, new HashSet() { "IfcAnnotation", "IfcProxy", "IfcOpeningStandardCase", "IfcBeamStandardCase", "IfcColumnStandardCase", "IfcDoorStandardCase", + { Ifc4x3Schema, new HashSet() { "IfcProxy", "IfcOpeningStandardCase", "IfcBeamStandardCase", "IfcColumnStandardCase", "IfcDoorStandardCase", "IfcMemberStandardCase", "IfcPlateStandardCase", "IfcSlabElementedCase", "IfcSlabStandardCase", "IfcWallElementedCase", "IfcWallStandardCase", "IfcWindowStandardCase", "IfcDoorStyle", "IfcWindowStyle", "IfcBuilding", "IfcBuildingStorey" } }, - { Ifc2x3Schema, new HashSet(){ "IfcAnnotation", "IfcElectricalElement", "IfcEquipmentElement", "IfcBuilding", "IfcBuildingStorey" } }, - { Ifc2x2Schema, new HashSet(){ "IfcAnnotation", "IfcBuilding", "IfcBuildingStorey" } } + { Ifc4Schema, new HashSet() { "IfcProxy", "IfcOpeningStandardCase", "IfcBeamStandardCase", "IfcColumnStandardCase", "IfcDoorStandardCase", + "IfcMemberStandardCase", "IfcPlateStandardCase", "IfcSlabElementedCase", "IfcSlabStandardCase", "IfcWallElementedCase", + "IfcWallStandardCase", "IfcWindowStandardCase", "IfcDoorStyle", "IfcWindowStyle", "IfcBuilding", "IfcBuildingStorey" } }, + { Ifc2x3Schema, new HashSet(){ "IfcElectricalElement", "IfcEquipmentElement", "IfcBuilding", "IfcBuildingStorey" } }, + { Ifc2x2Schema, new HashSet(){ "IfcBuilding", "IfcBuildingStorey" } } }; - static IDictionary m_IFCSchemaDict = new Dictionary(); - static IDictionary m_IFCSchemaTries { get; set; } - static IDictionary>> m_IFCEntityPredefTypeDict = new Dictionary>>(); + static IDictionary IFCSchemaDict { get; set; } = + new Dictionary(); + + static IDictionary IFCSchemaTries { get; set; } + + static IDictionary>> IFCEntityPredefTypeDict = new Dictionary>>(); /// /// return the standardized IFC schema name based on the various enumeration of IFCVersion @@ -257,16 +263,16 @@ static public IfcSchemaEntityTree GetEntityDictFor(IFCVersion ifcFileVersion) static public IfcSchemaEntityTree GetEntityDictFor(string schemaFile, string schemaLoc = null) { schemaFile = schemaFile.ToUpper(); - if (m_IFCSchemaDict.ContainsKey(schemaFile)) - return m_IFCSchemaDict[schemaFile]; + if (IFCSchemaDict.ContainsKey(schemaFile)) + return IFCSchemaDict[schemaFile]; // if not found, process the file and add into the static dictionary IfcSchemaEntityTree entityTree = PopulateEntityDictFor(schemaFile, schemaLoc); if (entityTree == null) return null; - m_IFCSchemaDict.Add(schemaFile, entityTree); - m_IFCEntityPredefTypeDict.Add(schemaFile, entityTree.PredefinedTypeEnumDict); + IFCSchemaDict.Add(schemaFile, entityTree); + IFCEntityPredefTypeDict.Add(schemaFile, entityTree.PredefinedTypeEnumDict); return entityTree; } @@ -323,28 +329,28 @@ static void ProcessSchemaFile(string dirLocation, ref HashSet schemaProc foreach (FileInfo fileInfo in dirInfo.GetFiles("*.xsd")) { string schemaId = Path.GetFileNameWithoutExtension(fileInfo.Name).ToUpper(); - if (!schemaProcessed.Contains(fileInfo.Name) && !m_IFCSchemaDict.ContainsKey(schemaId)) + if (!schemaProcessed.Contains(fileInfo.Name) && !IFCSchemaDict.ContainsKey(schemaId)) { IfcSchemaEntityTree entityTree = new IfcSchemaEntityTree(); bool success = ProcessIFCXMLSchema.ProcessIFCSchema(fileInfo, ref entityTree); if (success) { schemaProcessed.Add(fileInfo.Name); - m_IFCSchemaDict.Add(schemaId, entityTree); - m_IFCEntityPredefTypeDict.Add(schemaId, entityTree.PredefinedTypeEnumDict); + IFCSchemaDict.Add(schemaId, entityTree); + IFCEntityPredefTypeDict.Add(schemaId, entityTree.PredefinedTypeEnumDict); } } } } - static bool m_AllIFCSchemaProcessed = false; + static bool AllIFCSchemaProcessed { get; set; } = false; /// /// Get All IFC schema inside the designated folder. They will be cached /// static public void GetAllEntityDict() { - if (m_AllIFCSchemaProcessed) + if (AllIFCSchemaProcessed) return; HashSet schemaProcessed = new HashSet(); @@ -358,8 +364,8 @@ static public void GetAllEntityDict() ProcessSchemaFile(DirectoryUtil.IFCSchemaLocation, ref schemaProcessed); } - if (schemaProcessed.Count == m_IFCSchemaDict.Count) - m_AllIFCSchemaProcessed = true; + if (schemaProcessed.Count == IFCSchemaDict.Count) + AllIFCSchemaProcessed = true; } /// @@ -368,7 +374,7 @@ static public void GetAllEntityDict() /// The list of the schema trees static public IList GetAllCachedSchemaTrees() { - return m_IFCSchemaDict.Select(x => x.Value).ToList(); + return IFCSchemaDict.Select(x => x.Value).ToList(); } /// @@ -377,7 +383,7 @@ static public IList GetAllCachedSchemaTrees() /// the list of IFC schema names static public IList GetAllCachedSchemaNames() { - return m_IFCSchemaDict.Select(x => x.Key).ToList(); + return IFCSchemaDict.Select(x => x.Key).ToList(); } /// @@ -432,8 +438,7 @@ static public IfcSchemaEntityNode FindNonAbsInstanceSuperType(string context, st return res; } - string theTypeName = - typeName.Substring(typeName.Length - 4, 4).Equals("Type", StringComparison.CurrentCultureIgnoreCase) ? + string theTypeName = typeName.EndsWith("Type", StringComparison.CurrentCultureIgnoreCase) ? typeName : GetTypeNameFromInstanceName(typeName); IfcSchemaEntityNode entNode = ifcEntitySchemaTree.Find(theTypeName); @@ -679,9 +684,7 @@ static public IList GetPredefinedTypeList(IFCVersion context, string ifc /// List of PredefinedType strings static public IList GetPredefinedTypeList(IfcSchemaEntityTree ifcEntitySchemaTree, string ifcEntity) { - IList predefinedtypeList = new List(); - - if (ifcEntitySchemaTree == null || ifcEntitySchemaTree.IfcEntityDict == null || ifcEntitySchemaTree.IfcEntityDict.Count == 0) + if ((ifcEntitySchemaTree?.IfcEntityDict?.Count ?? 0) == 0) throw new Exception("Unable to locate IFC Schema xsd file! Make sure the relevant xsd exists."); if (string.IsNullOrEmpty(ifcEntity)) @@ -716,7 +719,9 @@ static public IList GetPredefinedTypeList(IfcSchemaEntityTree ifcEntityS public static bool IsDeprecatedOrUnsupported(string schemaName, string entityName) { if (DeprecatedOrUnsupportedDict.ContainsKey(schemaName)) + { return DeprecatedOrUnsupportedDict[schemaName].Contains(entityName); + } return false; } diff --git a/Source/Revit.IFC.Common/Utility/MathUtil.cs b/Source/Revit.IFC.Common/Utility/MathUtil.cs index be3a1c1b..4d24f71d 100644 --- a/Source/Revit.IFC.Common/Utility/MathUtil.cs +++ b/Source/Revit.IFC.Common/Utility/MathUtil.cs @@ -51,13 +51,8 @@ public class MathUtil /// /// Returns a small value for use in comparing doubles. /// - /// - /// The value. - /// - public static double Eps() - { - return 1.0e-9; - } + /// The value. + public static double Eps() => 1.0e-9; public static double SmallGap() { diff --git a/Source/Revit.IFC.Common/Utility/OptionsUtil.cs b/Source/Revit.IFC.Common/Utility/OptionsUtil.cs index f991fedb..2b6b581d 100644 --- a/Source/Revit.IFC.Common/Utility/OptionsUtil.cs +++ b/Source/Revit.IFC.Common/Utility/OptionsUtil.cs @@ -459,6 +459,9 @@ public static (string projectedCRSName, string projectedCRSDesc, string epsgCode BasePoint surveyPoint = BasePoint.GetSurveyPoint(doc); BasePoint projectBasePoint = BasePoint.GetProjectBasePoint(doc); + if (surveyPoint == null || projectBasePoint == null) + return (eastings, northings, orthogonalHeight, angleTN, origAngleTN); + (double svNorthings, double svEastings, double svElevation, double svAngle, double pbNorthings, double pbEastings, double pbElevation, double pbAngle) = ProjectLocationInfo(doc, surveyPoint.Position, projectBasePoint.Position); origAngleTN = pbAngle; diff --git a/Source/Revit.IFC.Export/Utility/SolidMeshGeometryInfo.cs b/Source/Revit.IFC.Common/Utility/SolidMeshGeometryInfo.cs similarity index 60% rename from Source/Revit.IFC.Export/Utility/SolidMeshGeometryInfo.cs rename to Source/Revit.IFC.Common/Utility/SolidMeshGeometryInfo.cs index 7723c739..6364bd8f 100644 --- a/Source/Revit.IFC.Export/Utility/SolidMeshGeometryInfo.cs +++ b/Source/Revit.IFC.Common/Utility/SolidMeshGeometryInfo.cs @@ -1,259 +1,334 @@ -// -// BIM IFC library: this library works with Autodesk(R) Revit(R) to export IFC files containing model geometry. -// Copyright (C) 2012 Autodesk, Inc. -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// -using System; -using System.Collections.Generic; - -using Autodesk.Revit.DB; -using Autodesk.Revit.DB.IFC; -using Revit.IFC.Common.Utility; - -namespace Revit.IFC.Export.Utility -{ - /// - /// A solid with extra pertinant information. - /// - public class SolidInfo - { - /// - /// The constructor. - /// - /// The solid. - /// The optional owner element for this solid. - public SolidInfo(Solid solid, Element ownerElement) - { - Solid = solid; - OwnerElement = ownerElement; - } - - /// - /// The contained solid. - /// - public Solid Solid { get; protected set; } - - /// - /// The element that contains the solid in its GeometryElement. - /// This is optional, and can be unset (null). - /// - public Element OwnerElement { get; protected set; } - } - - /// - /// A container class for lists of solids and meshes. - /// - /// - /// Added in 2013, this is a migration from the IFCSolidMeshGeometryInfo class - /// that is used within the BeamExporter, BodyExporter, WallExporter, - /// FamilyInstanceExporter and RepresentationUtil classes. - /// - public class SolidMeshGeometryInfo - { - // A list of collected solids, and the external element (if any) that generated them. - // In general, this will be this will be non-null if the geometry come from an - // Instance/Symbol pair, and will be the element that contains the geometry - // that the Instance is pointing to. - private IList m_SolidInfoList; - - // A list of collected meshes. - private List m_MeshesList; - - /// - /// Creates a default SolidMeshGeometryInfo with empty solidsList and meshesList. - /// - public SolidMeshGeometryInfo() - { - m_SolidInfoList = new List(); - m_MeshesList = new List(); - } - - /// - /// Appends a given Solid to the solidsList. - /// - /// - /// The Solid we are appending to the solidsList. - /// - public void AddSolid(Solid solidToAdd, Element externalElement) - { - m_SolidInfoList.Add(new SolidInfo(solidToAdd, externalElement)); - } - - /// - /// Appends a given Mesh to the meshesList. - /// - /// - /// The Mesh we are appending to the meshesList. - /// - public void AddMesh(Mesh meshToAdd) - { - m_MeshesList.Add(meshToAdd); - } - - /// - /// Returns the list of Solids and their generating external elements. - /// - /// We return a List instead of an IList for the AddRange functionality. - public List GetSolids() - { - List solids = new List(); - foreach (SolidInfo solidInfo in m_SolidInfoList) - { - solids.Add(solidInfo.Solid); - } - return solids; - } - - /// - /// Returns the list of Solids and their generating external elements. - /// - public IList GetSolidInfos() - { - return m_SolidInfoList; - } - - /// - /// Returns the list of Meshes. - /// - public List GetMeshes() - { - return m_MeshesList; - } - - /// - /// Returns the number of Solids in solidsList. - /// - public int SolidsCount() - { - return m_SolidInfoList.Count; - } - - /// - /// Returns the number of Meshes in meshesList. - /// - public int MeshesCount() - { - return m_MeshesList.Count; - } - - /// - /// This method takes the solidsList and clips all of its solids between the given range. - /// - /// The Element from which we obtain our BoundingBoxXYZ. - /// The top-level GeometryElement from which to gather X and Y - /// coordinates for the intersecting solid. - /// The IFCRange whose Z values we use to create an intersecting - /// solid to clip the solids in this class's internal solidsList. - /// If range boundaries are equal, method returns, performing no clippings. - public void ClipSolidsList(GeometryElement geomElem, IFCRange range) - { - if (geomElem == null) - { - throw new ArgumentNullException("geomElemToUse"); - } - - if (MathUtil.IsAlmostEqual(range.Start, range.End) || SolidsCount() == 0) - { - return; - } - - double bottomZ; - double boundDifference; - if (range.Start < range.End) - { - bottomZ = range.Start; - boundDifference = range.End - range.Start; - } - else - { - bottomZ = range.End; - boundDifference = range.Start - range.End; - } - - // create a new solid using the X and Y of the bounding box on the top level GeometryElement and the Z of the IFCRange - BoundingBoxXYZ elemBoundingBox = geomElem.GetBoundingBox(); - XYZ pointA = new XYZ(elemBoundingBox.Min.X, elemBoundingBox.Min.Y, bottomZ); - XYZ pointB = new XYZ(elemBoundingBox.Max.X, elemBoundingBox.Min.Y, bottomZ); - XYZ pointC = new XYZ(elemBoundingBox.Max.X, elemBoundingBox.Max.Y, bottomZ); - XYZ pointD = new XYZ(elemBoundingBox.Min.X, elemBoundingBox.Max.Y, bottomZ); - - List perimeter = new List(); - - try - { - perimeter.Add(Line.CreateBound(pointA, pointB)); - perimeter.Add(Line.CreateBound(pointB, pointC)); - perimeter.Add(Line.CreateBound(pointC, pointD)); - perimeter.Add(Line.CreateBound(pointD, pointA)); - } - catch - { - // One of the boundary lines was invalid. Do nothing. - return; - } - - List boxPerimeterList = new List(); - boxPerimeterList.Add(CurveLoop.Create(perimeter)); - Solid intersectionSolid = GeometryCreationUtilities.CreateExtrusionGeometry(boxPerimeterList, XYZ.BasisZ, boundDifference); - - // cycle through the elements in solidsList and intersect them against intersectionSolid to create a new list - List clippedSolidsList = new List(); - Solid currSolid; - - foreach (SolidInfo solidAndElement in m_SolidInfoList) - { - Solid solid = solidAndElement.Solid; - - try - { - // ExecuteBooleanOperation can throw if it fails. In this case, just ignore the clipping. - currSolid = BooleanOperationsUtils.ExecuteBooleanOperation(solid, intersectionSolid, BooleanOperationsType.Intersect); - if (currSolid != null && currSolid.Volume != 0) - { - clippedSolidsList.Add(new SolidInfo(currSolid, solidAndElement.OwnerElement)); - } - } - catch - { - // unable to perform intersection, add original solid instead - clippedSolidsList.Add(solidAndElement); - } - } - - m_SolidInfoList = clippedSolidsList; - } - - /// - /// Splits any solid volumes which consist of multiple closed bodies into individual solids (and updates the storage accordingly). - /// - public void SplitSolidsList() - { - IList splitSolidsList = new List(); - - foreach (SolidInfo solidInfo in m_SolidInfoList) - { - Element element = solidInfo.OwnerElement; - IList splitSolids = GeometryUtil.SplitVolumes(solidInfo.Solid); - foreach (Solid splitSolid in splitSolids) - { - splitSolidsList.Add(new SolidInfo(splitSolid, element)); - } - } - - m_SolidInfoList = splitSolidsList; - } - } +// +// BIM IFC library: this library works with Autodesk(R) Revit(R) to export IFC files containing model geometry. +// Copyright (C) 2012 Autodesk, Inc. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// +using System; +using System.Collections.Generic; +using System.Linq; +using Autodesk.Revit.DB; +using Autodesk.Revit.DB.IFC; + +namespace Revit.IFC.Common.Utility +{ + /// + /// A solid with extra pertinant information. + /// + public class SolidInfo + { + /// + /// The constructor. + /// + /// The solid. + /// The optional owner element for this solid. + public SolidInfo(Solid solid, Element ownerElement) + { + Solid = solid; + OwnerElement = ownerElement; + } + + /// + /// The contained solid. + /// + public Solid Solid { get; protected set; } + + /// + /// The element that contains the solid in its GeometryElement. + /// This is optional, and can be unset (null). + /// + public Element OwnerElement { get; protected set; } + } + + /// + /// A container class for lists of solids and meshes. + /// + /// + /// Added in 2013, this is a migration from the IFCSolidMeshGeometryInfo class + /// that is used within the BeamExporter, BodyExporter, WallExporter, + /// FamilyInstanceExporter and RepresentationUtil classes. + /// + public class SolidMeshGeometryInfo + { + // A list of collected solids, and the external element (if any) that generated them. + // In general, this will be this will be non-null if the geometry come from an + // Instance/Symbol pair, and will be the element that contains the geometry + // that the Instance is pointing to. + public IList SolidInfoList { get; set; } = new List(); + + // A list of collected meshes. + public List MeshesList { get; protected set; } = new List(); + + /// + /// Creates a default SolidMeshGeometryInfo with empty solidsList and meshesList. + /// + public SolidMeshGeometryInfo() + { + } + + /// + /// Appends a given Solid to the solidsList. + /// + /// + /// The Solid we are appending to the solidsList. + /// + public void AddSolid(Solid solidToAdd, Element externalElement) + { + SolidInfoList.Add(new SolidInfo(solidToAdd, externalElement)); + } + + /// + /// Appends a given Mesh to the meshesList. + /// + /// + /// The Mesh we are appending to the meshesList. + /// + public void AddMesh(Mesh meshToAdd) + { + MeshesList.Add(meshToAdd); + } + + /// + /// Returns the list of Solids and their generating external elements. + /// + /// We return a List instead of an IList for the AddRange functionality. + public List GetSolids() + { + List solids = new List(); + foreach (SolidInfo solidInfo in SolidInfoList) + { + solids.Add(solidInfo.Solid); + } + return solids; + } + + /// + /// Returns the list of Meshes. + /// + public List GetMeshes() + { + return MeshesList; + } + + /// + /// Returns the number of Solids in solidsList. + /// + public int SolidsCount() + { + return SolidInfoList.Count; + } + + /// + /// Returns the number of Meshes in meshesList. + /// + public int MeshesCount() + { + return MeshesList.Count; + } + + /// + /// This method takes the solidsList and clips all of its solids between the given range. + /// + /// The Element from which we obtain our BoundingBoxXYZ. + /// The top-level GeometryElement from which to gather X and Y + /// coordinates for the intersecting solid. + /// The IFCRange whose Z values we use to create an intersecting + /// solid to clip the solids in this class's internal solidsList. + /// If range boundaries are equal, method returns, performing no clippings. + public void ClipSolidsList(GeometryElement geomElem, IFCRange range) + { + if (geomElem == null) + { + throw new ArgumentNullException("geomElemToUse"); + } + + if (MathUtil.IsAlmostEqual(range.Start, range.End) || SolidsCount() == 0) + { + return; + } + + double bottomZ; + double boundDifference; + if (range.Start < range.End) + { + bottomZ = range.Start; + boundDifference = range.End - range.Start; + } + else + { + bottomZ = range.End; + boundDifference = range.Start - range.End; + } + + // create a new solid using the X and Y of the bounding box on the top level GeometryElement and the Z of the IFCRange + BoundingBoxXYZ elemBoundingBox = geomElem.GetBoundingBox(); + XYZ pointA = new XYZ(elemBoundingBox.Min.X, elemBoundingBox.Min.Y, bottomZ); + XYZ pointB = new XYZ(elemBoundingBox.Max.X, elemBoundingBox.Min.Y, bottomZ); + XYZ pointC = new XYZ(elemBoundingBox.Max.X, elemBoundingBox.Max.Y, bottomZ); + XYZ pointD = new XYZ(elemBoundingBox.Min.X, elemBoundingBox.Max.Y, bottomZ); + + List perimeter = new List(); + + try + { + perimeter.Add(Line.CreateBound(pointA, pointB)); + perimeter.Add(Line.CreateBound(pointB, pointC)); + perimeter.Add(Line.CreateBound(pointC, pointD)); + perimeter.Add(Line.CreateBound(pointD, pointA)); + } + catch + { + // One of the boundary lines was invalid. Do nothing. + return; + } + + List boxPerimeterList = new List(); + boxPerimeterList.Add(CurveLoop.Create(perimeter)); + Solid intersectionSolid = GeometryCreationUtilities.CreateExtrusionGeometry(boxPerimeterList, XYZ.BasisZ, boundDifference); + + // cycle through the elements in solidsList and intersect them against intersectionSolid to create a new list + List clippedSolidsList = new List(); + Solid currSolid; + + foreach (SolidInfo solidAndElement in SolidInfoList) + { + Solid solid = solidAndElement.Solid; + + try + { + // ExecuteBooleanOperation can throw if it fails. In this case, just ignore the clipping. + currSolid = BooleanOperationsUtils.ExecuteBooleanOperation(solid, intersectionSolid, BooleanOperationsType.Intersect); + if (currSolid != null && currSolid.Volume != 0) + { + clippedSolidsList.Add(new SolidInfo(currSolid, solidAndElement.OwnerElement)); + } + } + catch + { + // unable to perform intersection, add original solid instead + clippedSolidsList.Add(solidAndElement); + } + } + + SolidInfoList = clippedSolidsList; + } + + /// + /// Transforms a geometry by a given transform. + /// + /// The geometry element created by "GetTransformed" is a copy which will have its own allocated + /// membership - this needs to be stored and disposed of (see AllocatedGeometryObjectCache + /// for details) + /// The geometry. + /// The transform. + /// The cache that will prevent the data from being disposed. + /// The transformed geometry. + public static GeometryElement GetTransformedGeometry(GeometryElement geomElem, + Transform trf, AllocatedGeometryObjectCache geometryObjectCache) + { + if (geomElem == null) + return null; + + GeometryElement currGeomElem = geomElem.GetTransformed(trf); + geometryObjectCache.AddGeometryObject(currGeomElem); + return currGeomElem; + } + + + /// + /// Collects all solids and meshes within all nested levels of a given GeometryElement. + /// + /// + /// This is intended as a private helper method for the GetSolidMeshGeometry type collection methods. + /// + /// The GeometryElement we are collecting solids and meshes from. + /// The element that contains the geomElem. It can be null. + /// The initial Transform applied on the GeometryElement. + /// The cache that will prevent the data from being disposed. + private void CollectSolidMeshGeometry(GeometryElement geomElem, + Element containingElement, Transform trf, AllocatedGeometryObjectCache geometryObjectCache) + { + if (geomElem == null) + return; + + GeometryElement currGeomElem = geomElem; + Transform localTrf = trf; + if (localTrf == null) + localTrf = Transform.Identity; + else if (!localTrf.IsIdentity) + currGeomElem = GetTransformedGeometry(geomElem, localTrf, geometryObjectCache); + + // iterate through the GeometryObjects contained in the GeometryElement + foreach (GeometryObject geomObj in currGeomElem) + { + // Add try catch here because in a rare cases we find solid that throws exception/invalid solid.Faces + try + { + Solid solid = geomObj as Solid; + if (solid != null && solid.Faces.Size > 0) + { + AddSolid(solid, containingElement); + } + else + { + Mesh mesh = geomObj as Mesh; + if (mesh != null) + { + AddMesh(mesh); + } + else + { + // if the current geomObj is castable as a GeometryInstance, then we perform the same collection on its symbol geometry + GeometryInstance inst = geomObj as GeometryInstance; + + if (inst != null) + { + try + { + GeometryElement instanceSymbol = inst.GetSymbolGeometry(); + if (instanceSymbol != null && instanceSymbol.Count() != 0) + { + Transform instanceTransform = localTrf.Multiply(inst.Transform); + Element symbol = inst.GetDocument()?.GetElement(inst.GetSymbolGeometryId().SymbolId); + CollectSolidMeshGeometry(instanceSymbol, symbol, + instanceTransform, geometryObjectCache); + } + } + catch + { + } + } + } + } + } + catch + { + } + } + } + + /// + /// Collects all solids and meshes within all nested levels of a given GeometryElement. + /// + /// + /// This is intended as a helper method for the GetSolidMeshGeometry type collection methods. + /// + /// The GeometryElement we are collecting solids and meshes from. + public void CollectSolidMeshGeometry(GeometryElement geomElem, AllocatedGeometryObjectCache geometryObjectCache) + { + CollectSolidMeshGeometry(geomElem, null, Transform.Identity, geometryObjectCache); + } + } } \ No newline at end of file diff --git a/Source/Revit.IFC.Export/Exporter/AssemblyInstanceExporter.cs b/Source/Revit.IFC.Export/Exporter/AssemblyInstanceExporter.cs index d83448e4..0b57fc2b 100644 --- a/Source/Revit.IFC.Export/Exporter/AssemblyInstanceExporter.cs +++ b/Source/Revit.IFC.Export/Exporter/AssemblyInstanceExporter.cs @@ -232,9 +232,7 @@ public static void SetLocalPlacementsRelativeToAssembly(ExporterIFC exporterIFC, foreach (ElementId memberId in memberIds) { - IFCAnyHandle memberHnd = ExporterCacheManager.ElementToHandleCache.Find(memberId); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(memberHnd)) - memberHnds.Add(memberHnd); + memberHnds.AddIfNotNull(ExporterCacheManager.ElementToHandleCache.Find(memberId)); } if (memberHnds.Count == 0) diff --git a/Source/Revit.IFC.Export/Exporter/BeamExporter.cs b/Source/Revit.IFC.Export/Exporter/BeamExporter.cs index ca653156..a80ae327 100644 --- a/Source/Revit.IFC.Export/Exporter/BeamExporter.cs +++ b/Source/Revit.IFC.Export/Exporter/BeamExporter.cs @@ -224,9 +224,8 @@ private static IFCAnyHandle CreateBeamAxis(ExporterIFC exporterIFC, Element elem { IFCAnyHandle axisHnd = GeometryUtil.CreatePolyCurveFromCurve(exporterIFC, curve); axis_items = new List(); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(axisHnd)) + if (axis_items.AddIfNotNull(axisHnd)) { - axis_items.Add(axisHnd); representationTypeOpt = "Curve3D"; // We use Curve3D for IFC4RV Axis } } @@ -356,28 +355,23 @@ private static IFCAnyHandle CreateBeamAxis(ExporterIFC exporterIFC, Element elem } /// - /// Creates a new IfcBeamType and relates it to the current element. + /// Creates a new type entity appropriate to the object and relates it to the current element. /// /// The exporter. /// The ProductWrapper class. /// The element handle. /// The element. /// The material id used for the element type. - public static void ExportBeamType(ExporterIFC exporterIFC, ProductWrapper wrapper, IFCAnyHandle elementHandle, Element element, string predefinedType) + public static void ExportBeamType(ExporterIFC exporterIFC, ProductWrapper wrapper, IFCAnyHandle elementHandle, + Element element, IFCExportInfoPair exportType) { - if (elementHandle == null || element == null) + if (elementHandle == null) return; - Document doc = element.Document; - ElementId typeElemId = element.GetTypeId(); - ElementType elementType = doc.GetElement(typeElemId) as ElementType; + ElementType elementType = element?.Document?.GetElement(element?.GetTypeId()) as ElementType; if (elementType == null) return; - string preDefinedTypeSearch = predefinedType; - if (string.IsNullOrEmpty(preDefinedTypeSearch)) - preDefinedTypeSearch = "NULL"; - IFCExportInfoPair exportType = new IFCExportInfoPair(IFCEntityType.IfcBeamType, preDefinedTypeSearch); IFCAnyHandle beamType = ExporterCacheManager.ElementTypeToHandleCache.Find(elementType, exportType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(beamType)) { @@ -386,8 +380,8 @@ public static void ExportBeamType(ExporterIFC exporterIFC, ProductWrapper wrappe } // Property sets will be set later. - beamType = IFCInstanceExporter.CreateBeamType(exporterIFC.GetFile(), elementType, null, - null, null, predefinedType); + beamType = IFCInstanceExporter.CreateGenericIFCType(exportType, elementType, null, exporterIFC.GetFile(), + null, null); wrapper.RegisterHandleWithElementType(elementType, exportType, beamType, null); @@ -538,8 +532,7 @@ public static void ExportBeamType(ExporterIFC exporterIFC, ProductWrapper wrappe IList representations = new List(); double elevation = (setter.LevelInfo != null) ? setter.LevelInfo.Elevation : 0.0; IFCAnyHandle axisRep = CreateBeamAxis(exporterIFC, element, catId, axisInfo, offsetTransform, elevation); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(axisRep)) - representations.Add(axisRep); + representations.AddIfNotNull(axisRep); representations.Add(repHnd); Transform boundingBoxTrf = offsetTransform?.Inverse ?? Transform.Identity; @@ -550,8 +543,8 @@ public static void ExportBeamType(ExporterIFC exporterIFC, ProductWrapper wrappe IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations); string instanceGUID = GUIDUtil.CreateGUID(element); - beam = IFCInstanceExporter.CreateBeam(exporterIFC, element, instanceGUID, ExporterCacheManager.OwnerHistoryHandle, extrusionCreationData.GetLocalPlacement(), prodRep, exportType.ValidatedPredefinedType); - + beam = IFCInstanceExporter.CreateGenericIFCEntity(exportType, exporterIFC, element, instanceGUID, + ExporterCacheManager.OwnerHistoryHandle, extrusionCreationData.GetLocalPlacement(), prodRep); IFCAnyHandle mpSetUsage; if (materialProfileSet != null) @@ -559,7 +552,7 @@ public static void ExportBeamType(ExporterIFC exporterIFC, ProductWrapper wrappe productWrapper.AddElement(element, beam, setter, extrusionCreationData, true, exportType); - ExportBeamType(exporterIFC, productWrapper, beam, element, exportType.ValidatedPredefinedType); + ExportBeamType(exporterIFC, productWrapper, beam, element, exportType); OpeningUtil.CreateOpeningsIfNecessary(beam, element, extrusionCreationData, offsetTransform, exporterIFC, extrusionCreationData.GetLocalPlacement(), setter, productWrapper); diff --git a/Source/Revit.IFC.Export/Exporter/BodyExporter.cs b/Source/Revit.IFC.Export/Exporter/BodyExporter.cs index 3dba025d..ad9edff8 100644 --- a/Source/Revit.IFC.Export/Exporter/BodyExporter.cs +++ b/Source/Revit.IFC.Export/Exporter/BodyExporter.cs @@ -28,7 +28,6 @@ using Revit.IFC.Common.Enums; using Revit.IFC.Common.Utility; - namespace Revit.IFC.Export.Exporter { /// @@ -36,6 +35,19 @@ namespace Revit.IFC.Export.Exporter /// class BodyExporter { + class FaceSetInfo + { + public FaceSetInfo(HashSet faceSetHandles, bool isClosed) + { + FaceSetHandles = faceSetHandles; + IsClosed = isClosed; + } + + public HashSet FaceSetHandles { get; } = new HashSet(); + + public bool IsClosed { get; } = false; + } + /// /// Sets best material id for current export state. /// @@ -166,15 +178,18 @@ public static ElementId GetBestMaterialIdForGeometry(GeometryObject geometryObje if (!(geometryObject is Solid)) { + ElementId matId = ElementId.InvalidElementId; if (geometryObject is Mesh) { - ElementId matID = (geometryObject as Mesh).MaterialElementId; - if (ExporterUtil.IsElementIdBuiltInOrInvalid(matID)) - return ElementId.InvalidElementId; - - return matID; + matId = (geometryObject as Mesh).MaterialElementId; } - return ElementId.InvalidElementId; + else if (geometryObject is Face) + { + matId = (geometryObject as Face).MaterialElementId; + } + + return ExporterUtil.IsElementIdBuiltInOrInvalid(matId) ? ElementId.InvalidElementId : + matId; } Solid solid = geometryObject as Solid; @@ -244,7 +259,7 @@ public static ElementId GetBestMaterialIdForGeometry(GeometryObject geometryObje private static bool IsDuctCategory(ElementId categoryId) { long categoryValue = categoryId.Value; - return categoryValue == (long) BuiltInCategory.OST_DuctAccessory || + return categoryValue == (long)BuiltInCategory.OST_DuctAccessory || categoryValue == (long)BuiltInCategory.OST_DuctCurves || categoryValue == (long)BuiltInCategory.OST_DuctFitting || categoryValue == (long)BuiltInCategory.OST_DuctInsulations || @@ -273,7 +288,7 @@ private static bool CategoryHasMaterialIdParam(ElementId categoryId) // OST_Cornices also has a MaterialId parameter, but Revit doesn't want us // to ask for it. long categoryValue = categoryId.Value; - return categoryValue == (long) BuiltInCategory.OST_Rebar || + return categoryValue == (long)BuiltInCategory.OST_Rebar || categoryValue == (long)BuiltInCategory.OST_FabricReinforcement || categoryValue == (long)BuiltInCategory.OST_Fascia || categoryValue == (long)BuiltInCategory.OST_Gutter || @@ -305,10 +320,30 @@ private static bool CategoryHasStructuralMaterialParam(ElementId categoryId) } private static ElementId GetBestMaterialIdFromParameter(Element element) + { + if (element == null) + { + return ElementId.InvalidElementId; + } + + ElementId id = element.Id; + if (ExporterCacheManager.ElementIdMaterialParameterCache.TryGetValue(id, out ElementId matId)) + { + return matId; + } + + matId = CalcBestMaterialIdFromParameter(element); + ExporterCacheManager.ElementIdMaterialParameterCache[id] = matId; + return matId; + } + + private static ElementId CalcBestMaterialIdFromParameter(Element element) { ElementId matId = ExporterUtil.GetSingleMaterial(element); if (matId != ElementId.InvalidElementId) + { return matId; + } // Try to get it from the category of the element first. ElementId categoryId = CategoryUtil.GetSafeCategoryId(element); @@ -322,25 +357,34 @@ private static ElementId GetBestMaterialIdFromParameter(Element element) } if (matId != ElementId.InvalidElementId) + { return matId; + } // If not, try to get it from the system. ElementId systemTypeId = ElementId.InvalidElementId; if (IsDuctCategory(categoryId)) + { ParameterUtil.GetElementIdValueFromElement(element, BuiltInParameter.RBS_DUCT_SYSTEM_TYPE_PARAM, out systemTypeId); + } else if (IsPipeCategory(categoryId)) + { ParameterUtil.GetElementIdValueFromElement(element, BuiltInParameter.RBS_PIPING_SYSTEM_TYPE_PARAM, out systemTypeId); + } if (systemTypeId != ElementId.InvalidElementId) { Element systemType = element.Document.GetElement(systemTypeId); if (systemType != null) - return GetBestMaterialIdFromParameter(systemType); + { + matId = GetBestMaterialIdFromParameter(systemType); + return matId; + } } return matId; } - + /// /// Gets the best material id from the geometry or its structural material parameter. /// @@ -594,6 +638,71 @@ public static bool CanCreateClosedShell(Mesh mesh) return (unmatchedEdgeSz == 0); } + /// + /// Checks if the faces can create a closed shell. + /// + /// + /// Limitation: This could let through an edge shared an even number of times greater than 2. + /// + /// The collection of face handles. + /// True if can, false if can't. + /// This is an optimized version of CanCreateClosedShell(ICollection faceSet). + public static bool CanCreateClosedShell(ICollection>> faceSetIndices) + { + int numFaces = faceSetIndices.Count; + + // Do simple checks first. + if (numFaces < 4) + return false; + + // Try to match up edges. + IDictionary> unmatchedEdges = new Dictionary>(); + int unmatchedEdgeSz = 0; + + foreach (IList> face in faceSetIndices) + { + foreach (IList points in face) + { + int sizeOfBoundary = points.Count; + if (sizeOfBoundary < 3) + return false; + + for (int ii = 0; ii < sizeOfBoundary; ii++) + { + int pt1 = points[ii]; + int pt2 = points[(ii + 1) % sizeOfBoundary]; + + if (unmatchedEdges.TryGetValue(pt2, out IList unmatchedEdgesPt2) && + unmatchedEdgesPt2.Contains(pt1)) + { + unmatchedEdgesPt2.Remove(pt1); + unmatchedEdgeSz--; + } + else + { + if (unmatchedEdges.TryGetValue(pt1, out IList unmatchedEdgesPt1) && + unmatchedEdgesPt1.Contains(pt2)) + { + // An edge with the same orientation exists twice; can't create solid. + return false; + } + + if (unmatchedEdgesPt1 == null) + { + unmatchedEdgesPt1 = new List(); + unmatchedEdges[pt1] = unmatchedEdgesPt1; + } + + unmatchedEdgesPt1.Add(pt2); + unmatchedEdgeSz++; + } + } + } + } + + return (unmatchedEdgeSz == 0); + } + /// /// Checks if the faces can create a closed shell. /// @@ -670,65 +779,103 @@ public static bool CanCreateClosedShell(ICollection faceSet) return (unmatchedEdgeSz == 0); } - // This is a simplified routine for solids that are composed of planar faces with polygonal edges. This - // allows us to use the edges as the boundaries of the faces. + // This is a simplified routine for solids that are composed of planar faces with + // polygonal edges. This allows us to use the edges as the boundaries of the faces. private static bool ExportPlanarBodyIfPossible(ExporterIFC exporterIFC, Solid solid, - IList> currentFaceHashSetList, Transform lcs) + IList currentFaceHashSetList, Transform lcs) { IFCFile file = exporterIFC.GetFile(); + IList planarFaces = new List(); foreach (Face face in solid.Faces) { - if (!(face is PlanarFace)) + PlanarFace planarFace = face as PlanarFace; + if (planarFace == null) return false; - } - HashSet currentFaceSet = new HashSet(); - IDictionary vertexCache = new SortedDictionary(new GeometryUtil.XYZComparer()); + planarFaces.Add(planarFace); + } - foreach (Face face in solid.Faces) + double vertexTolerance = ExporterCacheManager.Document.Application.VertexTolerance; + IFCXYZFuzzyComparer ifcXYZFuzzyComparer = new IFCXYZFuzzyComparer(vertexTolerance); + + // Prepare polyloop data and check the polyloops for duplicate points before creating + // IFC instances to avoid unnecessary points and faces in the IFC document. + IDictionary>> polyloops = new Dictionary>>(); + ICollection>> faceSetIndices = new HashSet>>(); + foreach (PlanarFace planarFace in planarFaces) { - HashSet faceBounds = new HashSet(); - EdgeArrayArray edgeArrayArray = face.EdgeLoops; - - int edgeArraySize = edgeArrayArray.Size; - IList> edgeArrayVertices = new List>(); - - int outerEdgeArrayIndex = 0; - double maxArea = 0.0; // Only used/set if edgeArraySize > 1. - XYZ faceNormal = (face as PlanarFace).FaceNormal; + EdgeArrayArray edgeArrayArray = planarFace.EdgeLoops; + IList> edgeArrayVertices = new List>(); foreach (EdgeArray edgeArray in edgeArrayArray) { - IList vertices = new List(); - IList vertexXYZs = new List(); + ISet uniqueVertices = new SortedSet(ifcXYZFuzzyComparer); + IList vertices = new List(); foreach (Edge edge in edgeArray) { - Curve curve = edge.AsCurveFollowingFace(face); - + Curve curve = edge.AsCurveFollowingFace(planarFace); IList curvePoints = curve.Tessellate(); int numPoints = curvePoints.Count; - // Don't add last point to vertices, as this will be added in the next edge. for (int idx = 0; idx < numPoints - 1; idx++) { - if (!vertexCache.TryGetValue(curvePoints[idx], out IFCAnyHandle pointHandle)) - { - XYZ pointScaled = TransformAndScalePoint(exporterIFC, curvePoints[idx], lcs); - pointHandle = ExporterUtil.CreateCartesianPoint(file, pointScaled); - vertexCache[curvePoints[idx]] = pointHandle; - } + uniqueVertices.Add(curvePoints[idx]); + vertices.Add(curvePoints[idx]); + } + } + + // Polyloop contains duplicates or small edges + if (uniqueVertices.Count < 3) + { + return false; + } - vertices.Add(pointHandle); - vertexXYZs.Add(curvePoints[idx]); + edgeArrayVertices.Add(vertices); + } + + polyloops.Add(planarFace, edgeArrayVertices); + } + + HashSet currentFaceSet = new HashSet(); + IDictionary vertexCache = new SortedDictionary(ifcXYZFuzzyComparer); + foreach (KeyValuePair>> polyloop in polyloops) + { + IList> planarFaceIndices = new List>(); + + HashSet faceBounds = new HashSet(); + IList> edgeArrayVertices = new List>(); + XYZ faceNormal = polyloop.Key.FaceNormal; + int outerEdgeArrayIndex = 0; + int edgeArraySize = polyloop.Value.Count; + double? maxArea = null; // Only used/set if edgeArraySize > 1. + + foreach (IList edgeLoop in polyloop.Value) + { + IList edgeLoopIndices = new List(); + + IList vertices = new List(); + IList vertexXYZs = new List(); + + foreach (XYZ vertex in edgeLoop) + { + if (!vertexCache.TryGetValue(vertex, out IFCAnyHandle pointHandle)) + { + XYZ scaledPoint = TransformAndScalePoint(exporterIFC, vertex, lcs); + pointHandle = ExporterUtil.CreateCartesianPoint(file, scaledPoint); + vertexCache[vertex] = pointHandle; } + + vertices.Add(pointHandle); + edgeLoopIndices.Add(pointHandle.Id); + vertexXYZs.Add(vertex); } if (edgeArraySize > 1) { double currArea = Math.Abs(GeometryUtil.ComputePolygonalLoopArea(vertexXYZs, faceNormal, vertexXYZs[0])); - if (currArea > maxArea) + if (currArea > (maxArea ?? 0.0)) { outerEdgeArrayIndex = edgeArrayVertices.Count; maxArea = currArea; @@ -736,6 +883,7 @@ public static bool CanCreateClosedShell(ICollection faceSet) } edgeArrayVertices.Add(vertices); + planarFaceIndices.Add(edgeLoopIndices); } for (int ii = 0; ii < edgeArraySize; ii++) @@ -759,10 +907,16 @@ public static bool CanCreateClosedShell(ICollection faceSet) IFCAnyHandle currFace = IFCInstanceExporter.CreateFace(file, faceBounds); currentFaceSet.Add(currFace); } + + faceSetIndices.Add(planarFaceIndices); } if (currentFaceSet.Count > 0) - currentFaceHashSetList.Add(currentFaceSet); + { + bool canCreateClosedShell = CanCreateClosedShell(faceSetIndices); + currentFaceHashSetList.Add(new FaceSetInfo(currentFaceSet, canCreateClosedShell)); + } + return true; } @@ -1163,7 +1317,9 @@ private static bool ExportPlanarFacetsIfPossible(IFCFile file, TriangulatedShell bool sameSense, IDictionary cartesianPoints) { bool allowAdvancedCurve = !ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4; - IFCAnyHandle baseCurve = GeometryUtil.CreateIFCCurveFromRevitCurve(file, exporterIFC, curve, allowAdvancedCurve, cartesianPoints, false); + const GeometryUtil.TrimCurvePreference trimCurvePreference = GeometryUtil.TrimCurvePreference.BaseCurve; + IFCAnyHandle baseCurve = GeometryUtil.CreateIFCCurveFromRevitCurve(file, + exporterIFC, curve, allowAdvancedCurve, cartesianPoints, trimCurvePreference, null); if (IFCAnyHandleUtil.IsNullOrHasNoValue(baseCurve)) return null; @@ -1176,7 +1332,12 @@ private static bool ExportPlanarFacetsIfPossible(IFCFile file, TriangulatedShell IDictionary cartesianPoints, Transform additionalTrf = null) { bool allowAdvancedCurve = !ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4; - IFCAnyHandle ifcCurve = GeometryUtil.CreateIFCCurveFromRevitCurve(file, exporterIFC, curve, allowAdvancedCurve, cartesianPoints, true, additionalTrf); + const GeometryUtil.TrimCurvePreference trimCurvePreference = GeometryUtil.TrimCurvePreference.TrimmedCurve; + IFCAnyHandle ifcCurve = GeometryUtil.CreateIFCCurveFromRevitCurve(file, exporterIFC, + curve, allowAdvancedCurve, cartesianPoints, trimCurvePreference, additionalTrf); + if (IFCAnyHandleUtil.IsNullOrHasNoValue(ifcCurve)) + return null; + IFCAnyHandle sweptCurve = null; bool isBound = false; @@ -1569,9 +1730,15 @@ private static bool IsRightHanded(XYZ testPoint, XYZ axis, XYZ origin, XYZ uDeri return null; } - var sortedEdgeLoop = GeometryUtil.GetOuterLoopsWithInnerLoops(face); + var sortedEdgeLoop = GeometryUtil.GetOuterLoopsWithInnerLoops(face); + if (sortedEdgeLoop == null) + { + return null; + } + // check that we get back the same number of edgeloop int numberOfSortedEdgeLoop = 0; + foreach (var (outerLoop, innerLoops) in sortedEdgeLoop) { numberOfSortedEdgeLoop += 1 + innerLoops.Count; @@ -1581,7 +1748,7 @@ private static bool IsRightHanded(XYZ testPoint, XYZ axis, XYZ origin, XYZ uDeri { return null; } - + foreach (var (outerLoop, loops) in sortedEdgeLoop) { if (outerLoop == null || loops == null) @@ -1720,6 +1887,10 @@ private static bool IsRightHanded(XYZ testPoint, XYZ axis, XYZ origin, XYZ uDeri IFCAnyHandle axisPosition = IFCInstanceExporter.CreateAxis1Placement(file, location, axis); IFCAnyHandle sweptCurve = CreateProfileCurveFromCurve(file, exporterIFC, profileCurve, Resources.ConicalFaceProfileCurve, cartesianPoints); + if (IFCAnyHandleUtil.IsNullOrHasNoValue(sweptCurve)) + { + return null; + } // The profile position is optional in IFC4+. surface = IFCInstanceExporter.CreateSurfaceOfRevolution(file, sweptCurve, null, axisPosition); @@ -1756,6 +1927,10 @@ private static bool IsRightHanded(XYZ testPoint, XYZ axis, XYZ origin, XYZ uDeri IFCAnyHandle axisPosition = IFCInstanceExporter.CreateAxis1Placement(file, location, axis); IFCAnyHandle sweptCurve = CreateProfileCurveFromCurve(file, exporterIFC, profileCurve, Resources.RevolvedFaceProfileCurve, cartesianPoints); + if (IFCAnyHandleUtil.IsNullOrHasNoValue(sweptCurve)) + { + return null; + } // The profile position is optional in IFC4+. surface = IFCInstanceExporter.CreateSurfaceOfRevolution(file, sweptCurve, null, axisPosition); @@ -1827,6 +2002,10 @@ private static bool IsRightHanded(XYZ testPoint, XYZ axis, XYZ origin, XYZ uDeri IFCAnyHandle direction = ExporterUtil.CreateDirection(file, dirIFC); IFCAnyHandle sweptCurve = CreateProfileCurveFromCurve(file, exporterIFC, firstProfileCurve, Resources.RuledFaceProfileCurve, cartesianPoints, basePlaneTrf.Inverse); + if (IFCAnyHandleUtil.IsNullOrHasNoValue(sweptCurve)) + { + return null; + } surface = IFCInstanceExporter.CreateSurfaceOfLinearExtrusion(file, sweptCurve, sweptCurvePosition, direction, depth); } @@ -1937,17 +2116,26 @@ private static bool IsRightHanded(XYZ testPoint, XYZ axis, XYZ origin, XYZ uDeri return geomObjectPrimitives; } - private static IFCAnyHandle ExportPlanarSolidAsPolygonalFaceSet(ExporterIFC exporterIFC, Solid solid, IFCAnyHandle ifcColourRgbList, double opacity, - Transform trfToUse = null) + private static IEnumerable GetDataForExportPlanarSolidAsPolygonalFaceSet(Solid solid) { - IFCFile file = exporterIFC.GetFile(); - - bool isClosed = true; - IEnumerable faces = solid.Faces.OfType(); if (faces.Count() != solid.Faces.Size) // Not all faces in the solid were planar return null; + return faces; + } + + private static (IFCAnyHandle, int) ExportPlanarSolidAsPolygonalFaceSet(ExporterIFC exporterIFC, + IEnumerable faces, Transform trfToUse) + { + if (faces == null) + { + return (null, 0); + } + + IFCFile file = exporterIFC.GetFile(); + bool isClosed = true; + List ifcFaceHandles = new List(); // List of all unique vertex XYZs. Each item in this list is an average of all XYZs obtained from adjacent edge end-points. List vertexPositions = new List(); @@ -1973,7 +2161,7 @@ private static bool IsRightHanded(XYZ testPoint, XYZ axis, XYZ origin, XYZ uDeri { // This function isn't applicable to breps with non-linear curves if (!(edge.AsCurve() is Line)) - return null; + return (null, 0); isClosed = isClosed && (edge.GetFace(0) != null && edge.GetFace(1) != null); @@ -1986,7 +2174,7 @@ private static bool IsRightHanded(XYZ testPoint, XYZ axis, XYZ origin, XYZ uDeri { IList allEndPnts = SolidUtils.FindAllEdgeEndPointsAtVertex(endPnt); if (allEndPnts.Count == 0) - return null; + return (null, 0); // Use the average of all positions for the vertex location XYZ vertexPosition = XYZ.Zero; @@ -2023,13 +2211,13 @@ private static bool IsRightHanded(XYZ testPoint, XYZ axis, XYZ origin, XYZ uDeri if (indexedLoops.Count > 0) loopsCache.Add(new Tuple>, int>(indexedLoops, outerEdgeLoopIndex)); else - return null; + return (null, 0); } } catch { // If anything unexpected handles the caller should move on to export the body as a tessellation - return null; + return (null, 0); } // Create faces @@ -2050,10 +2238,25 @@ private static bool IsRightHanded(XYZ testPoint, XYZ axis, XYZ origin, XYZ uDeri vertexCoords.Add(new List() { vertexScaled.X, vertexScaled.Y, vertexScaled.Z }); } - if (ifcFaceHandles.Count == 0 || vertexCoords.Count == 0) - return null; + int numFaces = ifcFaceHandles.Count; + if (numFaces == 0 || vertexCoords.Count == 0) + return (null, 0); - return ExportIfcFacesAsPolygonalFaceSet(file, ifcFaceHandles, vertexCoords, isClosed, ifcColourRgbList, opacity); + IFCAnyHandle coordinatesHnd = IFCInstanceExporter.CreateCartesianPointList3D(file, vertexCoords); + IFCAnyHandle polygonalFaceSet = IFCInstanceExporter.CreatePolygonalFaceSet(file, coordinatesHnd, isClosed, ifcFaceHandles, null); + return (polygonalFaceSet, numFaces); + } + + private static void AddStyleToFaceSet(ExporterIFC exporterIFC, IFCFile file, + Document document, BodyExporterOptions options, IFCAnyHandle polygonalFaceSet, + IFCAnyHandle ifcColourRgbList, double opacity, ElementId matId, int numFaces) + { + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(ifcColourRgbList)) + { + IList colourIndex = Enumerable.Repeat(1, numFaces).ToList(); + IFCInstanceExporter.CreateIndexedColourMap(file, polygonalFaceSet, opacity, ifcColourRgbList, colourIndex); + } + CreateSurfaceStyleForRepItem(exporterIFC, document, options.CreatingVoid, polygonalFaceSet, matId); } /// @@ -2069,11 +2272,8 @@ private static bool IsRightHanded(XYZ testPoint, XYZ axis, XYZ origin, XYZ uDeri { IFCFile file = exporterIFC.GetFile(); - IFCAnyHandle ifcColourRgbList = GetBestColourAndOpacity(file, element, geomObject, - out double opacity, out ElementId matId); - Document document = element.Document; - IList polygonalFaceSetList = new List(); + List polygonalFaceSetList = new List(); // If the geomObject is GeometryELement or GeometryInstance, we need to collect their primitive Solid and Mesh first IList geomObjectPrimitives = GetGeometriesFromGeometryElement( @@ -2084,41 +2284,56 @@ private static bool IsRightHanded(XYZ testPoint, XYZ axis, XYZ origin, XYZ uDeri { try { + IList polygonalFaceSets = new List(); + + IList<(TriangleMergeUtil, bool)> triangleComponents = + new List<(TriangleMergeUtil, bool)>(); + IEnumerable planarFaceData = null; + if (geom is Solid) { Solid solid = geom as Solid; - IFCAnyHandle polygonalFaceSet = ExportPlanarSolidAsPolygonalFaceSet(exporterIFC, solid, ifcColourRgbList, opacity, trfToUse); - if (IFCAnyHandleUtil.IsNullOrHasNoValue(polygonalFaceSet)) + planarFaceData = GetDataForExportPlanarSolidAsPolygonalFaceSet(solid); + if (planarFaceData == null) { - TriangulatedSolidOrShell solidFacetation = SolidUtils.TessellateSolidOrShell(solid, options.TessellationControls); + TriangulatedSolidOrShell solidFacetation = GetOptimalTessellation(solid, options); + for (int ii = 0; ii < solidFacetation.ShellComponentCount; ++ii) { TriangulatedShellComponent component = solidFacetation.GetShellComponent(ii); - TriangleMergeUtil triMerge = new TriangleMergeUtil(component); - IList ifcFaces = MergeAndCreateIfcFaces(file, triMerge); - - IList> coordList = new List>(); - foreach (XYZ vertex in triMerge.GetVertices()) - { - XYZ vertexScaled = TransformAndScalePoint(exporterIFC, vertex, trfToUse); - coordList.Add(new List() { vertexScaled.X, vertexScaled.Y, vertexScaled.Z }); - } - - polygonalFaceSet = ExportIfcFacesAsPolygonalFaceSet(file, ifcFaces, coordList, component.IsClosed, ifcColourRgbList, opacity); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(polygonalFaceSet)) - polygonalFaceSetList.Add(polygonalFaceSet); + triangleComponents.Add((new TriangleMergeUtil(component), component.IsClosed)); } } - else - { - polygonalFaceSetList.Add(polygonalFaceSet); - } } else if (geom is Mesh) { Mesh mesh = geom as Mesh; - TriangleMergeUtil triMerge = new TriangleMergeUtil(mesh); + triangleComponents.Add((new TriangleMergeUtil(mesh), mesh.IsClosed)); + } + + if (planarFaceData == null && triangleComponents.Count == 0) + { + continue; + } + + IFCAnyHandle ifcColourRgbList = GetBestColourAndOpacity(file, element, geom, + out double opacity, out ElementId matId); + + if (planarFaceData != null) + { + (IFCAnyHandle polygonalFaceSet, int numFaces) = + ExportPlanarSolidAsPolygonalFaceSet(exporterIFC, planarFaceData, trfToUse); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(polygonalFaceSet)) + { + polygonalFaceSets.Add(polygonalFaceSet); + AddStyleToFaceSet(exporterIFC, file, document, options, polygonalFaceSet, + ifcColourRgbList, opacity, matId, numFaces); + } + } + + foreach ((TriangleMergeUtil triMerge, bool isClosed) in triangleComponents) + { IList ifcFaces = MergeAndCreateIfcFaces(file, triMerge); IList> coordList = new List>(); @@ -2128,36 +2343,75 @@ private static bool IsRightHanded(XYZ testPoint, XYZ axis, XYZ origin, XYZ uDeri coordList.Add(new List() { vertexScaled.X, vertexScaled.Y, vertexScaled.Z }); } - IFCAnyHandle polygonalFaceSet = ExportIfcFacesAsPolygonalFaceSet(file, ifcFaces, coordList, mesh.IsClosed, ifcColourRgbList, opacity); + IFCAnyHandle coordinatesHnd = IFCInstanceExporter.CreateCartesianPointList3D(file, coordList); + IFCAnyHandle polygonalFaceSet = IFCInstanceExporter.CreatePolygonalFaceSet(file, coordinatesHnd, isClosed, ifcFaces, null); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(polygonalFaceSet)) - polygonalFaceSetList.Add(polygonalFaceSet); + { + polygonalFaceSets.Add(polygonalFaceSet); + AddStyleToFaceSet(exporterIFC, file, document, options, polygonalFaceSet, + ifcColourRgbList, opacity, matId, ifcFaces.Count); + } } + + polygonalFaceSetList.AddRange(polygonalFaceSets); } catch { - // Failed! Likely because either the tessellation or coplanar face merge failed. Try to create from the faceset instead - IFCAnyHandle triangulatedMesh = ExportSurfaceAsTriangulatedFaceSet(exporterIFC, element, options, geomObject, trfToUse); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(triangulatedMesh)) - polygonalFaceSetList.Add(triangulatedMesh); + // Failed! Likely because either the tessellation or coplanar face merge failed. + // Try to create from the FaceSet instead. + polygonalFaceSetList.Clear(); + break; } } if (polygonalFaceSetList.Count == 0 && !allNotToBeExported) { // It is not from Solid, so we will use the faces to export. It works for Surface export too - IFCAnyHandle triangulatedMesh = ExportSurfaceAsTriangulatedFaceSet(exporterIFC, element, options, geomObject, trfToUse); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(triangulatedMesh)) - polygonalFaceSetList.Add(triangulatedMesh); + polygonalFaceSetList.AddRange(ExportSurfaceAsTriangulatedFaceSet(exporterIFC, element, + options, geomObject, trfToUse)); } - foreach (IFCAnyHandle polygonalFaceSet in polygonalFaceSetList) - CreateSurfaceStyleForRepItem(exporterIFC, document, options.CreatingVoid, polygonalFaceSet, matId); - return polygonalFaceSetList; } /// - /// COllect Solid and/or Mesh from GeometryElement + /// Tesselate the solid decreasing the number of facets if necessary. + /// + /// The Solid + /// The body exported options. + /// Solid tessellation + private static TriangulatedSolidOrShell GetOptimalTessellation(Solid solid, BodyExporterOptions options) + { + TriangulatedSolidOrShell solidFacetation = SolidUtils.TessellateSolidOrShell(solid, options.TessellationControls); + + SolidOrShellTessellationControls coarseTessellationControls = ExporterUtil.CopyTessellationControls(options.TessellationControls); + BodyExporterOptions.SetDefaultCoarseTessellationControls(coarseTessellationControls); + + if (AreTessellationControlsEqual(coarseTessellationControls, options.TessellationControls)) + { + // The tessellation controls are already at the coarsest level. + return solidFacetation; + } + + bool useCoarseTessellation = false; + for (int ii = 0; ii < solidFacetation.ShellComponentCount; ii++) + { + TriangulatedShellComponent component = solidFacetation.GetShellComponent(ii); + if (component.TriangleCount > MaximumAllowedFacets(options)) + { + useCoarseTessellation = true; + break; + } + } + + if (useCoarseTessellation) + solidFacetation = SolidUtils.TessellateSolidOrShell(solid, coarseTessellationControls); + + return solidFacetation; + } + + /// + /// Collect Solid and/or Mesh from GeometryElement /// /// the GeometryElement /// list of Solid and/or Mesh @@ -2183,24 +2437,13 @@ private static List GetGeometryObjectListFromGeometryElement(Doc private static IList MergeAndCreateIfcFaces(IFCFile file, TriangleMergeUtil triMerge) { // TODO: Look at performance implications of large facetations. - bool ignoreMerge = false; IList faces = new List(); - try + const bool tryToMerge = true; + if (!triMerge.SimplifyAndMergeFaces(tryToMerge)) { - triMerge.SimplifyAndMergeFaces(ignoreMerge); - } - catch - { - if (ignoreMerge) - { - return faces; - } - else - { - triMerge.Reset(); - triMerge.SimplifyAndMergeFaces(false); - } + triMerge.Reset(); + triMerge.SimplifyAndMergeFaces(!tryToMerge); } @@ -2230,27 +2473,6 @@ private static IList MergeAndCreateIfcFaces(IFCFile file, Triangle return faces; } - /// - /// Exports Ifc Faces as a single IfcPolygonalFaceSet with an associated colour map - /// - /// the File - /// IFC face handles - /// coordinate list - /// indicates whether the mesh is closed - /// Handle of the RGB colour list - /// Opacity of the colour map - /// IFC handle for the PolygeonalFaceSet - private static IFCAnyHandle ExportIfcFacesAsPolygonalFaceSet(IFCFile file, IList ifcFaceHandles, IList> coordList, bool isClosed, IFCAnyHandle ifcColourRgbList, double? opacity) - { - IFCAnyHandle coordinatesHnd = IFCInstanceExporter.CreateCartesianPointList3D(file, coordList); - IFCAnyHandle polygonalFaceSet = IFCInstanceExporter.CreatePolygonalFaceSet(file, coordinatesHnd, isClosed, ifcFaceHandles, null); - IList colourIndex = Enumerable.Repeat(1, ifcFaceHandles.Count).ToList(); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(ifcColourRgbList) && !IFCAnyHandleUtil.IsNullOrHasNoValue(polygonalFaceSet)) - IFCInstanceExporter.CreateIndexedColourMap(file, polygonalFaceSet, opacity, ifcColourRgbList, colourIndex); - - return polygonalFaceSet; - } - private static int MaximumAllowedFacets(BodyExporterOptions options) { // We are going to limit the number of triangles to 25000 for Coarse tessellation, and 50000 otherwise. @@ -2259,6 +2481,121 @@ private static int MaximumAllowedFacets(BodyExporterOptions options) return (options.TessellationLevel == BodyExporterOptions.BodyTessellationLevel.Coarse) ? 25000 : 50000; } + private static (IList>, IList>) GetMeshCoordinateInfo( + ExporterIFC exporterIFC, Mesh mesh, Transform lcs, BodyExporterOptions options) + { + // Note that this function has two possible return values: + // (coordList, coordIdx) == (empty, empty): Unhandled or empty mesh. + // Anything else: valid data. + IList> coordList = new List>(); + IList> coordIdx = new List>(); + + int numberOfTriangles = mesh.NumTriangles; + int numberOfVertices = mesh.Vertices.Count; + + // We are going to limit the number of triangles to prevent the solid faceter from creating too many extra triangles to sew the surfaces. + if (numberOfTriangles == 0 || numberOfVertices == 0 || numberOfTriangles >= MaximumAllowedFacets(options)) + { + return (coordList, coordIdx); + } + + // create list of vertices first. + foreach (XYZ vertex in mesh.Vertices) + { + XYZ vertexScaled = TransformAndScalePoint(exporterIFC, vertex, lcs); + coordList.Add(new List(3) { vertexScaled.X, vertexScaled.Y, vertexScaled.Z }); + } + // Create the entity IfcCartesianPointList3D from the List of List and assign it to attribute Coordinates of IfcTriangulatedFaceSet + + // Export all of the triangles + for (int ii = 0; ii < numberOfTriangles; ii++) + { + MeshTriangle triangle = mesh.get_Triangle(ii); + // IFC uses index that starts with 1 instead of 0 (following similar standard in X3D) + coordIdx.Add(new List(3) + { + (int)triangle.get_Index(0) + 1, + (int)triangle.get_Index(1) + 1, + (int)triangle.get_Index(2) + 1 + }); + } + + return (coordList, coordIdx); + } + + private static (IList>, IList>) GetSolidCoordinateInfo( + ExporterIFC exporterIFC, Solid solid, Transform lcs, BodyExporterOptions options) + { + // Note that this function has three possible return values: + // (coordList, coordIdx) == (null, null): Exception thrown because of invalid data. + // (coordList, coordIdx) == (empty, empty): Unhandled or empty geometry. + // Anything else: valid data. + IList> coordList = new List>(); + IList> coordIdx = new List>(); + + try + { + SolidOrShellTessellationControls tessellationControls = options.TessellationControls; + TriangulatedSolidOrShell solidFacetation = + SolidUtils.TessellateSolidOrShell(solid, tessellationControls); + + // Only handle one solid or shell. + if (solidFacetation.ShellComponentCount != 1) + { + return (coordList, coordIdx); + } + + TriangulatedShellComponent component = solidFacetation.GetShellComponent(0); + int numberOfTriangles = component.TriangleCount; + int numberOfVertices = component.VertexCount; + + // We are going to limit the number of triangles to prevent the solid faceter from creating too many extra triangles to sew the surfaces. + if (numberOfTriangles == 0 || numberOfVertices == 0 || numberOfTriangles >= MaximumAllowedFacets(options)) + { + return (coordList, coordIdx); + } + + // create list of vertices first. + for (int ii = 0; ii < numberOfVertices; ii++) + { + XYZ vertex = component.GetVertex(ii); + XYZ vertexScaled = TransformAndScalePoint(exporterIFC, vertex, lcs); + coordList.Add(new List(3) { vertexScaled.X, vertexScaled.Y, vertexScaled.Z }); + } + // Create the entity IfcCartesianPointList3D from the List of List and assign it to attribute Coordinates of IfcTriangulatedFaceSet + + // Export all of the triangles + for (int ii = 0; ii < numberOfTriangles; ii++) + { + TriangleInShellComponent triangle = component.GetTriangle(ii); + // IFC uses index that starts with 1 instead of 0 (following similar standard in X3D) + coordIdx.Add(new List(3) { triangle.VertexIndex0 + 1, triangle.VertexIndex1 + 1, triangle.VertexIndex2 + 1 }); + } + } + catch + { + return (null, null); + } + + return (coordList, coordIdx); + } + + private static (IList>, IList>) GetGeometryCoordinateInfo( + ExporterIFC exporterIFC, GeometryObject geom, Transform lcs, BodyExporterOptions options) + { + if (geom is Solid) + { + return GetSolidCoordinateInfo(exporterIFC, geom as Solid, lcs, options); + } + else if (geom is Mesh) + { + return GetMeshCoordinateInfo(exporterIFC, geom as Mesh, lcs, options); + } + + // Return an empty list, to signify no error, just ignored. Really shouldn't get here. + return (new List>(), new List>()); + } + /// /// Export Geometry in IFC4 Triangulated tessellation /// @@ -2273,152 +2610,76 @@ private static int MaximumAllowedFacets(BodyExporterOptions options) IFCFile file = exporterIFC.GetFile(); Document document = element.Document; - IFCAnyHandle ifcColourRgbList = GetBestColourAndOpacity(file, element, - geomObject, out double opacity, out ElementId matId); - - IList triangulatedBodyList = new List(); + List triangulatedBodyList = new List(); List colourIndex = new List(); - // We need to collect all SOlids and Meshes from the GeometryObject if it is of types GeometryElement or GeometryInstance + // We need to collect all Solids and Meshes from the GeometryObject if it is of types GeometryElement or GeometryInstance // If the geomObject is GeometryELement or GeometryInstance, we need to collect their primitive Solid and Mesh first IList geomObjectPrimitives = GetGeometriesFromGeometryElement( exporterIFC, document, geomObject, true, out bool allNotToBeExported); - // At this point the collection will only contains Solids and/or Meshes. Loop through each of them + // At this point the collection will only contains Solids and/or Meshes. + // Loop through each of them. + // Note that we will collect all of the coordList and coordIdx first since if any fail, + // we will fall back to ExportSurfaceAsTriangulatedFaceSet. + + IList<(GeometryObject, IList>, IList>)> coordListsAndIndices = + new List<(GeometryObject, IList>, IList>)>(); foreach (GeometryObject geom in geomObjectPrimitives) { - if (geom is Solid) - { - try - { - Solid solid = geom as Solid; - - SolidOrShellTessellationControls tessellationControls = options.TessellationControls; - TriangulatedSolidOrShell solidFacetation = - SolidUtils.TessellateSolidOrShell(solid, tessellationControls); - - // Only handle one solid or shell. - if (solidFacetation.ShellComponentCount == 1) - { - TriangulatedShellComponent component = solidFacetation.GetShellComponent(0); - int numberOfTriangles = component.TriangleCount; - int numberOfVertices = component.VertexCount; - - // We are going to limit the number of triangles to prevent the solid faceter from creating too many extra triangles to sew the surfaces. - if ((numberOfTriangles > 0 && numberOfVertices > 0) && (numberOfTriangles < MaximumAllowedFacets(options))) - { - IList> coordList = new List>(); - IList> coordIdx = new List>(); - - // create list of vertices first. - for (int ii = 0; ii < numberOfVertices; ii++) - { - XYZ vertex = component.GetVertex(ii); - XYZ vertexScaled = TransformAndScalePoint(exporterIFC, vertex, lcs); - coordList.Add(new List(3) { vertexScaled.X, vertexScaled.Y, vertexScaled.Z }); - } - // Create the entity IfcCartesianPointList3D from the List of List and assign it to attribute Coordinates of IfcTriangulatedFaceSet - - // Export all of the triangles - for (int ii = 0; ii < numberOfTriangles; ii++) - { - TriangleInShellComponent triangle = component.GetTriangle(ii); - // IFC uses index that starts with 1 instead of 0 (following similar standard in X3D) - coordIdx.Add(new List(3) { triangle.VertexIndex0 + 1, triangle.VertexIndex1 + 1, triangle.VertexIndex2 + 1 }); - } - - // Create attribute CoordIndex from the List of List of the IfcTriangulatedFaceSet - - IFCAnyHandle coordPointLists = IFCAnyHandleUtil.CreateInstance(file, IFCEntityType.IfcCartesianPointList3D); - IFCAnyHandleUtil.SetAttribute(coordPointLists, "CoordList", coordList, 1, null, 3, 3); + IList> coordList = new List>(); + IList> coordIdx = new List>(); + (coordList, coordIdx) = GetGeometryCoordinateInfo(exporterIFC, geom, lcs, options); - IFCAnyHandle triangulatedBody = IFCAnyHandleUtil.CreateInstance(file, IFCEntityType.IfcTriangulatedFaceSet); - IFCAnyHandleUtil.SetAttribute(triangulatedBody, "Coordinates", coordPointLists); - IFCAnyHandleUtil.SetAttribute(triangulatedBody, "CoordIndex", coordIdx, 1, null, 3, 3); - - // Currently each face will refer to just a single color in ColourRgbList - colourIndex.AddRange(Enumerable.Repeat(1, numberOfTriangles)); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(ifcColourRgbList) && !IFCAnyHandleUtil.IsNullOrHasNoValue(triangulatedBody)) - IFCInstanceExporter.CreateIndexedColourMap(file, triangulatedBody, opacity, ifcColourRgbList, colourIndex); - - triangulatedBodyList.Add(triangulatedBody); - } - } - } - catch - { - // Failed! Likely because of the tessellation failed. Try to create from the faceset instead - IFCAnyHandle triangulatedMesh = ExportSurfaceAsTriangulatedFaceSet(exporterIFC, element, options, geomObject, lcs); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(triangulatedMesh)) - triangulatedBodyList.Add(triangulatedMesh); - } - } - else if (geom is Mesh) + // Failed; go to fallback. + if (coordList == null || coordIdx == null) { - Mesh mesh = geom as Mesh; - - int numberOfTriangles = mesh.NumTriangles; - int numberOfVertices = mesh.Vertices.Count; - - // We are going to limit the number of triangles to prevent the solid faceter from creating too many extra triangles to sew the surfaces. - if ((numberOfTriangles > 0 && numberOfVertices > 0) && (numberOfTriangles < MaximumAllowedFacets(options))) - { - IList> coordList = new List>(); - IList> coordIdx = new List>(); - - // create list of vertices first. - foreach (XYZ vertex in mesh.Vertices) - { - XYZ vertexScaled = TransformAndScalePoint(exporterIFC, vertex, lcs); - coordList.Add(new List(3) { vertexScaled.X, vertexScaled.Y, vertexScaled.Z }); - } - // Create the entity IfcCartesianPointList3D from the List of List and assign it to attribute Coordinates of IfcTriangulatedFaceSet + coordListsAndIndices.Clear(); + break; + } - // Export all of the triangles - for (int ii = 0; ii < numberOfTriangles; ii++) - { - MeshTriangle triangle = mesh.get_Triangle(ii); - // IFC uses index that starts with 1 instead of 0 (following similar standard in X3D) - coordIdx.Add(new List(3) - { - (int)triangle.get_Index(0) + 1, - (int)triangle.get_Index(1) + 1, - (int)triangle.get_Index(2) + 1 - }); - } + if (coordList.Count > 0 && coordIdx.Count > 0) + { + coordListsAndIndices.Add((geom, coordList, coordIdx)); + } + } - // Create attribute CoordIndex from the List of List of the IfcTriangulatedFaceSet + foreach ((GeometryObject geom, IList> coordList, IList> coordIdx) in coordListsAndIndices) + { + IFCAnyHandle coordPointLists = IFCAnyHandleUtil.CreateInstance(file, IFCEntityType.IfcCartesianPointList3D); + IFCAnyHandleUtil.SetAttribute(coordPointLists, "CoordList", coordList, 1, null, 3, 3); - IFCAnyHandle coordPointLists = IFCAnyHandleUtil.CreateInstance(file, IFCEntityType.IfcCartesianPointList3D); - IFCAnyHandleUtil.SetAttribute(coordPointLists, "CoordList", coordList, 1, null, 3, 3); + IFCAnyHandle triangulatedBody = IFCAnyHandleUtil.CreateInstance(file, IFCEntityType.IfcTriangulatedFaceSet); + IFCAnyHandleUtil.SetAttribute(triangulatedBody, "Coordinates", coordPointLists); + IFCAnyHandleUtil.SetAttribute(triangulatedBody, "CoordIndex", coordIdx, 1, null, 3, 3); - IFCAnyHandle triangulatedBody = IFCAnyHandleUtil.CreateInstance(file, IFCEntityType.IfcTriangulatedFaceSet); - IFCAnyHandleUtil.SetAttribute(triangulatedBody, "Coordinates", coordPointLists); - IFCAnyHandleUtil.SetAttribute(triangulatedBody, "CoordIndex", coordIdx, 1, null, 3, 3); + triangulatedBodyList.Add(triangulatedBody); - // Currently each face will refer to just a single color in ColourRgbList - colourIndex.AddRange(Enumerable.Repeat(1, numberOfTriangles)); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(ifcColourRgbList) && !IFCAnyHandleUtil.IsNullOrHasNoValue(triangulatedBody)) - IFCInstanceExporter.CreateIndexedColourMap(file, triangulatedBody, opacity, ifcColourRgbList, colourIndex); + IFCAnyHandle ifcColourRgbList = GetBestColourAndOpacity(file, element, + geom, out double opacity, out ElementId matId); - triangulatedBodyList.Add(triangulatedBody); - } + // Currently each face will refer to just a single color in ColourRgbList + colourIndex.AddRange(Enumerable.Repeat(1, coordIdx.Count)); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(ifcColourRgbList) && + !IFCAnyHandleUtil.IsNullOrHasNoValue(triangulatedBody)) + { + IFCInstanceExporter.CreateIndexedColourMap(file, triangulatedBody, opacity, ifcColourRgbList, colourIndex); + } + if (matId != ElementId.InvalidElementId) + { + CreateSurfaceStyleForRepItem(exporterIFC, document, options.CreatingVoid, + triangulatedBody, matId); } } - if ((triangulatedBodyList == null || triangulatedBodyList.Count == 0) && !allNotToBeExported) + if (triangulatedBodyList.Count == 0 && !allNotToBeExported) { - // It is not from Solid, so we will use the faces to export. It works for Surface export too - IFCAnyHandle triangulatedMesh = ExportSurfaceAsTriangulatedFaceSet(exporterIFC, element, options, geomObject, lcs); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(triangulatedMesh)) - triangulatedBodyList.Add(triangulatedMesh); + triangulatedBodyList.AddRange(ExportSurfaceAsTriangulatedFaceSet(exporterIFC, element, + options, geomObject, lcs)); } - - foreach (IFCAnyHandle triangulatedBody in triangulatedBodyList) - CreateSurfaceStyleForRepItem(exporterIFC, document, options.CreatingVoid, triangulatedBody, matId); - + return triangulatedBodyList; } @@ -2431,7 +2692,7 @@ private static int MaximumAllowedFacets(BodyExporterOptions options) /// geometry objects /// returns a handle public static IList ExportBodyAsTessellatedFaceSet(ExporterIFC exporterIFC, Element element, BodyExporterOptions options, - GeometryObject geomObject, Transform lcs = null) + GeometryObject geomObject, Transform lcs = null) { IList tessellatedBodyList = null; @@ -2447,10 +2708,10 @@ private static int MaximumAllowedFacets(BodyExporterOptions options) return tessellatedBodyList; } - private static IFCAnyHandle GetBestColourAndOpacity(IFCFile file, Element element, - GeometryObject geometryObject, out double opacity, out ElementId bestMaterialId) + private static (Color, double, ElementId) GetBestColourAndOpacity(Element element, + GeometryObject geometryObject) { - bestMaterialId = GetBestMaterialIdFromGeometryOrParameter(geometryObject, element); + ElementId bestMaterialId = GetBestMaterialIdFromGeometryOrParameter(geometryObject, element); Color exportColor = null; Material matElem = (bestMaterialId != null && bestMaterialId != ElementId.InvalidElementId) ? @@ -2466,68 +2727,117 @@ private static int MaximumAllowedFacets(BodyExporterOptions options) exportColor = CategoryUtil.GetSafeColor(matElem.Color); } - opacity = (double)(100 - (matElem?.Transparency ?? 0)) / 100; + double opacity = (double)(100 - (matElem?.Transparency ?? 0)) / 100; // For now we will only support a single color for the tessellation since there is no // good way to associate the face and the color. + return (exportColor, opacity, bestMaterialId); + } + + private static IFCAnyHandle GetBestColourAndOpacity(IFCFile file, Element element, + GeometryObject geometryObject, out double opacity, out ElementId bestMaterialId) + { + Color exportColor; + (exportColor, opacity, bestMaterialId) = GetBestColourAndOpacity(element, geometryObject); + return (exportColor == null) ? null : ColourRgbListFromColor(file, exportColor); } /// - /// Return a triangulated face set from the list of faces + /// Return a list of triangulated face sets from the geometry. /// - /// exporter IFC - /// the element - /// the body export options - /// the geometry object - /// returns the handle - private static IFCAnyHandle ExportSurfaceAsTriangulatedFaceSet(ExporterIFC exporterIFC, Element element, BodyExporterOptions options, - GeometryObject geomObject, Transform trfToUse = null) + /// The exporterIFC class. + /// The element. + /// The body exporter options. + /// The geometry object. + /// Returns a list of handles. + private static IList ExportSurfaceAsTriangulatedFaceSet( + ExporterIFC exporterIFC, Element element, BodyExporterOptions options, + GeometryObject geomObject, Transform trfToUse = null) { IFCFile file = exporterIFC.GetFile(); + IList listOfIndexedTriangles = new List(); - IFCAnyHandle ifcColourRgbList = GetBestColourAndOpacity(file, element, geomObject, - out double opacity, out _); - - IList colourIndex = new List(); - - List> triangleList = new List>(); + List<(List>, Color, double, ElementId)> triangleLists = + new List<(List>, Color, double, ElementId)>(); - if (geomObject is Solid) - { - triangleList = GetTriangleListFromSolid(geomObject, options, trfToUse); - } - else if (geomObject is Mesh) - { - triangleList = GetTriangleListFromMesh(geomObject, trfToUse); - } - // There is also a possibility that the geomObject is an GeometryElement thaat is a collection of GeometryObjects. Go through the collection and get the Mesh, Solid, or Face in it - else if (geomObject is GeometryElement) + if (geomObject is GeometryElement) { - // We will skip the line geometries if they are in the IEnumerable + // There is also a possibility that the geomObject is an GeometryElement thaat is a + // collection of GeometryObjects. Go through the collection and get the Meshes, Solids, + // and Faces. We will skip everything else. + + // NOTE: We might have some "duplicate" colors in the list below. For now, we will + // allow that, since it is really a very minor optimization to compact the colors. foreach (GeometryObject geom in (geomObject as GeometryElement)) { if (geom is Solid) - triangleList.AddRange(GetTriangleListFromSolid(geom, options, trfToUse)); - if (geom is Mesh) - triangleList.AddRange(GetTriangleListFromMesh(geom, trfToUse)); - if (geom is Face) + { + triangleLists.AddRange(GetTriangleListsFromSolid(exporterIFC, element, geom, options, trfToUse)); + } + else if (geom is Mesh) + { + triangleLists.Add(GetTriangleListFromMesh(exporterIFC, element, geom, trfToUse, null)); + } + else if (geom is Face) { Mesh faceMesh = (geom as Face).Triangulate(); - triangleList.AddRange(GetTriangleListFromMesh(faceMesh, trfToUse)); + triangleLists.Add(GetTriangleListFromMesh(exporterIFC, element, faceMesh, trfToUse, geom)); } + else + { + continue; + } + } + } + else + { + if (geomObject is Solid) + { + triangleLists.AddRange(GetTriangleListsFromSolid(exporterIFC, element, geomObject, options, trfToUse)); + } + else if (geomObject is Mesh) + { + triangleLists.Add(GetTriangleListFromMesh(exporterIFC, element, geomObject, trfToUse, null)); + } + else + { + return listOfIndexedTriangles; } } - IFCAnyHandle indexedTriangles = GeometryUtil.GetIndexedTriangles(file, triangleList); - for (int faceCnt = 0; faceCnt < triangleList.Count; ++faceCnt) + Document document = element?.Document; + foreach ((List> triangleList, Color color, double opacity, + ElementId matId) in triangleLists) { - colourIndex.Add(1); // Currently each face will refer to just a single color in ColourRgbList + if (triangleList.Count == 0) + { + continue; + } + + IFCAnyHandle indexedTriangles = GeometryUtil.GetIndexedTriangles(file, triangleList); + + IFCAnyHandle ifcColourRgbList = ColourRgbListFromColor(file, color); + + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(indexedTriangles)) + { + List colourIndex = Enumerable.Repeat(1, triangleList.Count).ToList(); + + listOfIndexedTriangles.Add(indexedTriangles); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(ifcColourRgbList)) + { + IFCInstanceExporter.CreateIndexedColourMap(file, indexedTriangles, opacity, ifcColourRgbList, colourIndex); + } + + if (matId != ElementId.InvalidElementId) + { + CreateSurfaceStyleForRepItem(exporterIFC, document, options.CreatingVoid, + indexedTriangles, matId); + } + } } - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(ifcColourRgbList) && !IFCAnyHandleUtil.IsNullOrHasNoValue(indexedTriangles)) - IFCInstanceExporter.CreateIndexedColourMap(file, indexedTriangles, opacity, ifcColourRgbList, colourIndex); - return indexedTriangles; + return listOfIndexedTriangles; } private static bool AreTessellationControlsEqual(SolidOrShellTessellationControls first, SolidOrShellTessellationControls second) @@ -2551,7 +2861,7 @@ private static bool AreTessellationControlsEqual(SolidOrShellTessellationControl } private static bool ExportBodyAsSolid(ExporterIFC exporterIFC, Element element, BodyExporterOptions options, - IList> currentFaceHashSetList, GeometryObject geomObject, Transform lcs) + IList currentFaceHashSetList, GeometryObject geomObject, Transform lcs) { IFCFile file = exporterIFC.GetFile(); Document document = element.Document; @@ -2575,7 +2885,8 @@ private static bool AreTessellationControlsEqual(SolidOrShellTessellationControl // 2. Try tessellationControlsOriginal, but only if they are different. // 3. Try a coarse tessellation, but only if the original wasn't coarse. bool useSolidTessellation = false; - for (int pass = 0; pass < 3; pass++) + const int finalPass = 2; + for (int pass = 0; pass <= finalPass; pass++) { SolidOrShellTessellationControls tessellationControlsToUse = null; @@ -2617,11 +2928,17 @@ private static bool AreTessellationControlsEqual(SolidOrShellTessellationControl break; } } - catch + catch (Exception ex) { - string errMsg = String.Format("TessellateSolidOrShell failed in IFC export for element \"{0}\" with id {1}", element.Name, element.Id); + string errMsg = String.Format("Pass {0}: TessellateSolidOrShell failed in IFC export for reason: \"{1}\" in element \"{2}\" with id {3}", pass, ex.Message, element.Name, element.Id); document.Application.WriteJournalComment(errMsg, false/*timestamp*/); - return false; + + // If the facetation failed, but we can try again, lets do so. + if (pass == finalPass) + { + return false; + } + continue; } } @@ -2674,7 +2991,10 @@ private static bool AreTessellationControlsEqual(SolidOrShellTessellationControl } } } - currentFaceHashSetList.Add(currentFaceSet); + + // Current assumption: if it was a Solid in Revit, don't spend the time to validate + // the result. + currentFaceHashSetList.Add(new FaceSetInfo(currentFaceSet, true)); // Call GC.KeepAlive(solidFacetation) at this point to maintain a reference to solidFacetation // and prevent the object deletion by the garbage collector after try-catch block. @@ -2698,7 +3018,7 @@ private static bool AreTessellationControlsEqual(SolidOrShellTessellationControl // Can't resetMaterials if we already have partially populated our body items with extrusions (canExportSolidModelRep) int numExtrusions = bodyItems.Count; bool resetMaterials = (numExtrusions == 0); - IList> currentFaceHashSetList = new List>(); + IList currentFaceHashSetList = new List(); IList startIndexForObject = new List(); BodyData bodyData = BodyData.Create(bodyDataIn, resetMaterials); @@ -2752,11 +3072,13 @@ private static bool AreTessellationControlsEqual(SolidOrShellTessellationControl // First, see if this could be represented as a simple swept solid. if (exportAsBReps && (currAnalyzer != null)) { - SweptSolidExporter sweptSolidExporter = SweptSolidExporter.Create(exporterIFC, element, currAnalyzer, geomObject); + SweptSolidExporter sweptSolidExporter = SweptSolidExporter.Create(exporterIFC, element, currAnalyzer, + geomObject, GenerateAdditionalInfo.GenerateBody, isCoarse); HashSet facetHnds = sweptSolidExporter?.Facets; if (facetHnds != null && facetHnds.Count != 0) { - currentFaceHashSetList.Add(facetHnds); + // Current assumption: SweptSolidExporter produces valid solid geometry. + currentFaceHashSetList.Add(new FaceSetInfo(facetHnds, true)); alreadyExported = true; GraphicsStyle style = document.GetElement(geomObject.GraphicsStyleId) as GraphicsStyle; bodyData.AddRepresentationItemInfo(document, style, materialId, sweptSolidExporter.RepresentationItem); @@ -2782,7 +3104,7 @@ private static bool AreTessellationControlsEqual(SolidOrShellTessellationControl Transform trfToUse = null; if (instanceGeometry) trfToUse = GeometryUtil.GetScaledTransform(exporterIFC); - else if (!instanceGeometry && element.AssemblyInstanceId != ElementId.InvalidElementId) + else if (!instanceGeometry && ExporterUtil.IsContainedInAssembly(element)) trfToUse = Transform.Identity; // If we are using the Reference View, try a triangulated face set. @@ -2791,7 +3113,7 @@ private static bool AreTessellationControlsEqual(SolidOrShellTessellationControl if (!alreadyExported && canExportAsTessellatedFaceSet) { IList triangulatedBodyItems = ExportBodyAsTessellatedFaceSet(exporterIFC, element, options, geomObject, trfToUse); - if (triangulatedBodyItems != null && triangulatedBodyItems.Count > 0) + if ((triangulatedBodyItems?.Count ?? 0) > 0) { GraphicsStyle style = document.GetElement(geomObject.GraphicsStyleId) as GraphicsStyle; foreach (IFCAnyHandle triangulatedBodyItem in triangulatedBodyItems) @@ -2831,9 +3153,13 @@ private static bool AreTessellationControlsEqual(SolidOrShellTessellationControl if (currentFaceSet.Count == 0) continue; + // Default is true until we see that it is false. This generally maintains + // current behavior, but probably needs to be improved. + bool canExportAsClosedShell = true; + if (exportAsBReps) { - bool canExportAsClosedShell = (currentFaceSet.Count >= 4); + canExportAsClosedShell = (currentFaceSet.Count >= 4); if (canExportAsClosedShell) { if ((geomObject is Mesh) && (numBReps == 1)) @@ -2878,7 +3204,7 @@ private static bool AreTessellationControlsEqual(SolidOrShellTessellationControl } } - currentFaceHashSetList.Add(new HashSet(currentFaceSet)); + currentFaceHashSetList.Add(new FaceSetInfo(new HashSet(currentFaceSet), canExportAsClosedShell)); } } } @@ -2906,11 +3232,19 @@ private static bool AreTessellationControlsEqual(SolidOrShellTessellationControl } else { - startIndexForObject.Add(currentFaceHashSetList.Count); // end index for last object. + int size = currentFaceHashSetList.Count; + startIndexForObject.Add(size); // end index for last object. + + for (int ii = 0; ii < size && exportAsBReps; ii++) + { + if (!currentFaceHashSetList[ii].IsClosed) + { + exportAsBReps = false; + } + } IList repMapItems = new List(); - int size = currentFaceHashSetList.Count; if (exportAsBReps) { int brepIndex = -1; @@ -2924,14 +3258,13 @@ private static bool AreTessellationControlsEqual(SolidOrShellTessellationControl currMatId = materialIds[brepIndex]; currStyle = document.GetElement(splitGeometryList[brepIndex].GraphicsStyleId) as GraphicsStyle; } - HashSet currentFaceHashSet = currentFaceHashSetList[ii]; + HashSet currentFaceHashSet = currentFaceHashSetList[ii].FaceSetHandles; IFCAnyHandle faceOuter = IFCInstanceExporter.CreateClosedShell(file, currentFaceHashSet); - IFCAnyHandle brepHnd = RepresentationUtil.CreateFacetedBRep(exporterIFC, document, - options.CreatingVoid, faceOuter, currMatId); + IFCAnyHandle brepHnd = RepresentationUtil.CreateFacetedBRep(exporterIFC, + document, options.CreatingVoid, faceOuter, currMatId); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(brepHnd)) + if (bodyItems.AddIfNotNull(brepHnd)) { - bodyItems.Add(brepHnd); bodyData.AddRepresentationItemInfo(document, currStyle, currMatId, brepHnd); } } @@ -2942,7 +3275,7 @@ private static bool AreTessellationControlsEqual(SolidOrShellTessellationControl int matToUse = -1; for (int ii = 0; ii < size; ii++) { - HashSet currentFaceHashSet = currentFaceHashSetList[ii]; + HashSet currentFaceHashSet = currentFaceHashSetList[ii].FaceSetHandles; if (startIndexForObject[matToUse + 1] == ii) matToUse++; @@ -3113,6 +3446,7 @@ public override int GetHashCode() // If we are exporting a coarse tessellation, or regardless if the level of detail isn't set to the highest level, // we will try to see if we can use an optimized BRep created from a swept solid. + bool isCoarse = options.TessellationLevel == BodyExporterOptions.BodyTessellationLevel.Coarse; bool allowExportAsOptimizedBRep = (options.TessellationLevel == BodyExporterOptions.BodyTessellationLevel.Coarse || ExporterCacheManager.ExportOptionsCache.LevelOfDetail < ExportOptionsCache.ExportTessellationLevel.High); bool allowAdvancedBReps = !ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4 @@ -3374,9 +3708,8 @@ public override int GetHashCode() Transform lcs = Transform.Identity; IFCAnyHandle extrusionHandle = ExtrusionExporter.CreateExtrudedSolidFromExtrusionData(exporterIFC, element, extrusionLists[ii][0], out lcs, profileName: profileName); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(extrusionHandle)) + if (bodyItems.AddIfNotNull(extrusionHandle)) { - bodyItems.Add(extrusionHandle); materialIdsForExtrusions.Add(exporterIFC.GetMaterialIdForCurrentExportState()); IList curveLoops = extrusionLists[ii][0].GetLoops(); @@ -3412,7 +3745,7 @@ public override int GetHashCode() exportBodyParams.ScaledWidth = UnitUtil.ScaleLength(width); } - double area = ExporterIFCUtils.ComputeAreaOfCurveLoops(curveLoops); + double area = ExporterIFCUtils.ComputeAreaOfCurveLoops(new[] { curveLoops[0] }); if (area > 0.0) { exportBodyParams.ScaledArea = UnitUtil.ScaleArea(area); @@ -3476,12 +3809,12 @@ public override int GetHashCode() if (options.CollectFootprintHandle) addInfo |= GenerateAdditionalInfo.GenerateFootprint; - SweptSolidExporter sweptSolidExporter = SweptSolidExporter.Create(exporterIFC, element, simpleSweptSolidAnalyzer, solid, addInfo: addInfo); + SweptSolidExporter sweptSolidExporter = SweptSolidExporter.Create(exporterIFC, element, + simpleSweptSolidAnalyzer, solid, addInfo, isCoarse); IFCAnyHandle sweptHandle = sweptSolidExporter?.RepresentationItem; - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(sweptHandle)) + if (bodyItems.AddIfNotNull(sweptHandle)) { - bodyItems.Add(sweptHandle); ElementId matId = exporterIFC.GetMaterialIdForCurrentExportState(); materialIdsForExtrusions.Add(matId); GraphicsStyle style = document.GetElement(solid.GraphicsStyleId) as GraphicsStyle; @@ -3754,76 +4087,99 @@ static BodyData SaveMaterialAndFootprintInfo(BodyData bodyData, MaterialAndProfi return bodyData; } - static List> GetTriangleListFromSolid(GeometryObject geomObject, BodyExporterOptions options, Transform trfToUse) + static IList<(List>, Color, double, ElementId)> GetTriangleListsFromSolid( + ExporterIFC exporterIFC, Element element, GeometryObject geomObject, + BodyExporterOptions options, Transform trfToUse) { - List> triangleList = new List>(); + IDictionary>, Color, double>> triangleListDict = + new SortedDictionary>, Color, double>>(); + Solid geomSolid = geomObject as Solid; FaceArray faces = geomSolid.Faces; - double scale = UnitUtil.ScaleLengthForRevitAPI(); // The default tessellationLevel is -1, which is illegal for Triangulate. Get a value in range. double tessellationLevel = options.TessellationControls.LevelOfDetail; if (tessellationLevel < 0.0) + { tessellationLevel = ((double)ExporterCacheManager.ExportOptionsCache.LevelOfDetail) / 4.0; + } foreach (Face face in faces) { Mesh faceTriangulation = face.Triangulate(tessellationLevel); - if (faceTriangulation != null) + if (faceTriangulation == null) { - for (int ii = 0; ii < faceTriangulation.NumTriangles; ++ii) - { - List triangleVertices = new List(); - MeshTriangle triangle = faceTriangulation.get_Triangle(ii); - for (int tri = 0; tri < 3; ++tri) - { - XYZ vert = scale * triangle.get_Vertex(tri); - if (trfToUse != null) - vert = trfToUse.OfPoint(vert); - - triangleVertices.Add(vert); - } - triangleList.Add(triangleVertices); - } + continue; } - else + + (List> triangleList, Color color, double opacity, ElementId matId) = + GetTriangleListFromMesh(exporterIFC, element, faceTriangulation, trfToUse, face); + long matIdAsLong = matId.Value; + if (!triangleListDict.TryGetValue(matIdAsLong, out Tuple>, Color, double> currList)) { - // TODO: log the information to the user since it will mean missing face for this geometry though the failure is probably because the face is too thin or self intersecting + List> emptyTriangleList = new List>(); + currList = Tuple.Create(emptyTriangleList, color, opacity); + triangleListDict[matIdAsLong] = currList; } + currList.Item1.AddRange(triangleList); + } + + IList<(List>, Color, double, ElementId)> triangleLists = new + List<(List>, Color, double, ElementId)>(); + + foreach (KeyValuePair>, Color, double>> data in triangleListDict) + { + (List>, Color, double, ElementId) triangleList = + (data.Value.Item1, data.Value.Item2, data.Value.Item3, new ElementId(data.Key)); + triangleLists.Add(triangleList); } - return triangleList; + + return triangleLists; } - static List> GetTriangleListFromMesh(GeometryObject geomObject, Transform trfToUse) + static (List>, Color, double, ElementId) GetTriangleListFromMesh( + ExporterIFC exporterIFC, Element element, GeometryObject geomObject, Transform trfToUse, GeometryObject parentObject) { List> triangleList = new List>(); Mesh geomMesh = geomObject as Mesh; - double scale = UnitUtil.ScaleLengthForRevitAPI(); + for (int ii = 0; ii < geomMesh.NumTriangles; ++ii) { List triangleVertices = new List(); MeshTriangle triangle = geomMesh.get_Triangle(ii); for (int tri = 0; tri < 3; ++tri) { - XYZ vert = scale * triangle.get_Vertex(tri); - if (trfToUse != null) - vert = trfToUse.OfPoint(vert); - + XYZ vert = TransformAndScalePoint(exporterIFC, triangle.get_Vertex(tri), trfToUse); triangleVertices.Add(vert); } triangleList.Add(triangleVertices); } - return triangleList; + + (Color color, double opacity, ElementId matId) = GetBestColourAndOpacity(element, parentObject ?? geomObject); + return (triangleList, color, opacity, matId); + } + + static IList ColorToRgb(Color color) + { + double blueVal = (color?.Blue ?? 127.0) / 255.0; + double greenVal = (color?.Green ?? 127.0) / 255.0; + double redVal = (color?.Red ?? 127.0) / 255.0; + return new List() { redVal, greenVal, blueVal }; } static IFCAnyHandle ColourRgbListFromColor(IFCFile file, Color matColor) { - double blueVal = matColor.Blue / 255.0; - double greenVal = matColor.Green / 255.0; - double redVal = matColor.Red / 255.0; + IList> colourRgbList = new List>() { ColorToRgb(matColor) }; + return IFCInstanceExporter.CreateColourRgbList(file, colourRgbList); + } + + static IFCAnyHandle ColourRgbListFromColors(IFCFile file, IList matColors) + { IList> colourRgbList = new List>(); - IList rgbVal = new List() { redVal, greenVal, blueVal }; - colourRgbList.Add(rgbVal); + foreach (Color matColor in matColors) + { + colourRgbList.Add(ColorToRgb(matColor)); + } return IFCInstanceExporter.CreateColourRgbList(file, colourRgbList); } diff --git a/Source/Revit.IFC.Export/Exporter/CeilingExporter.cs b/Source/Revit.IFC.Export/Exporter/CeilingExporter.cs index eefce354..320d4408 100644 --- a/Source/Revit.IFC.Export/Exporter/CeilingExporter.cs +++ b/Source/Revit.IFC.Export/Exporter/CeilingExporter.cs @@ -50,7 +50,7 @@ class CeilingExporter /// public static void ExportCeilingElement(ExporterIFC exporterIFC, Ceiling ceiling, ref GeometryElement geomElement, ProductWrapper productWrapper) { - string ifcEnumType = ExporterUtil.GetIFCTypeFromExportTable(exporterIFC, ceiling); + string ifcEnumType = ExporterUtil.GetIFCTypeFromExportTable(ceiling); string pdefFromParam = ExporterUtil.GetExportTypeFromTypeParameter(ceiling, null); if (!String.IsNullOrEmpty(pdefFromParam)) ifcEnumType = pdefFromParam; @@ -81,7 +81,7 @@ public static void ExportCovering(ExporterIFC exporterIFC, Element element, ref // For IFC4RV export, Element will be split into its parts(temporarily) in order to export the wall by its parts // If Parts are created by code and not by user then their name should be equal to Material name. bool setMaterialNameToPartName = ExporterUtil.CreateParts(element, layersetInfo.MaterialIds.Count, ref geomElem); - ExporterUtil.ExportPartAs exportPartAs = ExporterUtil.CanExportByComponentsOrParts(element); + ExporterUtil.ExportPartAs exportPartAs = ExporterUtil.CanExportByComponentsOrParts(element, ref geomElem); bool exportByComponents = exportPartAs == ExporterUtil.ExportPartAs.ShapeAspect; bool exportParts = exportPartAs == ExporterUtil.ExportPartAs.Part; @@ -106,20 +106,15 @@ public static void ExportCovering(ExporterIFC exporterIFC, Element element, ref ecData.PossibleExtrusionAxes = (element is FamilyInstance) ? IFCExtrusionAxes.TryXYZ : IFCExtrusionAxes.TryZ; BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow); - if (exportByComponents) - { - prodRep = RepresentationUtil.CreateProductDefinitionShapeWithoutBodyRep(exporterIFC, element, categoryId, geomElem, representations); - } - else + if (!exportByComponents) { prodRep = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, element, categoryId, geomElem, bodyExporterOptions, null, ecData, true); - } - - if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodRep)) - { - ecData.ClearOpenings(); - return; + if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodRep)) + { + ecData.ClearOpenings(); + return; + } } } @@ -136,6 +131,13 @@ public static void ExportCovering(ExporterIFC exporterIFC, Element element, ref string instanceGUID = GUIDUtil.CreateGUID(element); string coveringType = IFCValidateEntry.GetValidIFCPredefinedTypeType(ifcEnumType, defaultCoveringEnumType, "IfcCoveringType"); + if (exportByComponents) + { + prodRep = RepresentationUtil.CreateProductDefinitionShapeWithoutBodyRep(exporterIFC, element, categoryId, geomElem, representations); + IFCAnyHandle hostShapeRepFromParts = PartExporter.ExportHostPartAsShapeAspects(exporterIFC, element, prodRep, + productWrapper, setter, setter.LocalPlacement, ElementId.InvalidElementId, layersetInfo, ecData); + } + IFCAnyHandle covering = IFCInstanceExporter.CreateCovering(exporterIFC, element, instanceGUID, ExporterCacheManager.OwnerHistoryHandle, setter.LocalPlacement, prodRep, coveringType); @@ -143,11 +145,7 @@ public static void ExportCovering(ExporterIFC exporterIFC, Element element, ref { PartExporter.ExportHostPart(exporterIFC, element, covering, productWrapper, setter, setter.LocalPlacement, null, setMaterialNameToPartName); } - else if (exportByComponents) - { - IFCAnyHandle hostShapeRepFromParts = PartExporter.ExportHostPartAsShapeAspects(exporterIFC, element, prodRep, - productWrapper, setter, setter.LocalPlacement, ElementId.InvalidElementId, layersetInfo, ecData); - } + ExporterUtil.AddIntoComplexPropertyCache(covering, layersetInfo); @@ -191,7 +189,7 @@ public static void ExportCovering(ExporterIFC exporterIFC, Element element, ref if (ceiling != null) { HostObjectExporter.ExportHostObjectMaterials(exporterIFC, ceiling, covering, - geomElem, productWrapper, ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis3, null, null); + geomElem, productWrapper, ElementId.InvalidElementId, IFCLayerSetDirection.Axis3, null, null); } else { diff --git a/Source/Revit.IFC.Export/Exporter/CurtainSystemExporter.cs b/Source/Revit.IFC.Export/Exporter/CurtainSystemExporter.cs index 5b7ada15..a09742ec 100644 --- a/Source/Revit.IFC.Export/Exporter/CurtainSystemExporter.cs +++ b/Source/Revit.IFC.Export/Exporter/CurtainSystemExporter.cs @@ -33,21 +33,12 @@ namespace Revit.IFC.Export.Exporter /// class CurtainSystemExporter { - /// - /// Exports curtain object as container. + /// Exports a curtain object as container. /// - /// - /// Collection of elements contained in the host curtain element. - /// - /// - /// The curtain wall element. - /// - /// - /// The ExporterIFC object. - /// - /// - /// The ProductWrapper. - /// + /// Collection of elements contained in the host curtain element. + /// The curtain system element. + /// The ExporterIFC object. + /// The ProductWrapper. public static void ExportCurtainObjectCommonAsContainer(ICollection allSubElements, Element wallElement, ExporterIFC exporterIFC, ProductWrapper origWrapper, PlacementSetter currSetter) { @@ -74,7 +65,7 @@ class CurtainSystemExporter alreadyVisited.Add(subElem.Id); // Respect element visibility settings. - if (!ElementFilteringUtil.CanExportElement(exporterIFC, subElem, false) || !ElementFilteringUtil.IsElementVisible(subElem)) + if (!ElementFilteringUtil.CanExportElement(subElem, false) || !ElementFilteringUtil.IsElementVisible(subElem)) continue; GeometryElement geomElem = subElem.get_Geometry(geomOptions); @@ -85,62 +76,13 @@ class CurtainSystemExporter { if (subElem is FamilyInstance) { - string ifcEnumType; - IFCExportInfoPair exportType = ExporterUtil.GetProductExportType(exporterIFC, subElem, out ifcEnumType); + IFCExportInfoPair exportType = ExporterUtil.GetProductExportType(exporterIFC, subElem, out _); - if (subElem is Mullion) - { - if (ExporterCacheManager.ExportOptionsCache.ExportAs2x2) - ProxyElementExporter.Export(exporterIFC, subElem, geomElem, productWrapper, exportType); - else - { - IFCAnyHandle currLocalPlacement = currSetter.LocalPlacement; - - if (exportType.ExportInstance == IFCEntityType.IfcCurtainWall) - { - // By default, panels and mullions are set to the same category as their parent. In this case, - // ask to get the exportType from the category id, since we don't want to inherit the parent class. - exportType.SetValueWithPair(IFCEntityType.IfcMemberType, "MULLION"); - } - - FamilyInstanceExporter.ExportFamilyInstanceAsMappedItem(exporterIFC, subElem as Mullion, exportType, exportType.ValidatedPredefinedType, productWrapper, - ElementId.InvalidElementId, null, currLocalPlacement); - } - } - else + IFCAnyHandle currLocalPlacement = currSetter.LocalPlacement; + using (IFCExportBodyParams extraParams = new IFCExportBodyParams()) { - FamilyInstance subFamInst = subElem as FamilyInstance; - - if (exportType.ExportInstance == IFCEntityType.IfcCurtainWall) - { - // By default, panels and mullions are set to the same category as their parent. In this case, - // ask to get the exportType from the category id, since we don't want to inherit the parent class. - ElementId catId = CategoryUtil.GetSafeCategoryId(subElem); - exportType = ElementFilteringUtil.GetExportTypeFromCategoryId(catId); - } - - - if (ExporterCacheManager.ExportOptionsCache.ExportAs2x2) - { - if ((exportType.ExportInstance == IFCEntityType.UnKnown) || - (exportType.ExportInstance == IFCEntityType.IfcPlate) || - (exportType.ExportInstance == IFCEntityType.IfcMember)) - exportType.SetValueWithPair(IFCEntityType.IfcBuildingElementProxy, ifcEnumType); - } - else - { - if (exportType.ExportInstance == IFCEntityType.UnKnown) - { - exportType.SetValueWithPair(IFCEntityType.IfcPlateType, "CURTAIN_PANEL"); - } - } - - IFCAnyHandle currLocalPlacement = currSetter.LocalPlacement; - using (IFCExportBodyParams extraParams = new IFCExportBodyParams()) - { - FamilyInstanceExporter.ExportFamilyInstanceAsMappedItem(exporterIFC, subFamInst, exportType, ifcEnumType, productWrapper, - ElementId.InvalidElementId, null, currLocalPlacement); - } + FamilyInstanceExporter.ExportFamilyInstanceAsMappedItem(exporterIFC, + subElem as FamilyInstance, exportType, productWrapper, ElementId.InvalidElementId, null, currLocalPlacement); } } else if (subElem is CurtainGridLine) @@ -164,26 +106,13 @@ class CurtainSystemExporter /// /// Exports curtain object as one Brep. /// - /// - /// Collection of elements contained in the host curtain element. - /// - /// - /// The curtain wall element. - /// - /// - /// The ExporterIFC object. - /// - /// - /// The PlacementSetter object. - /// - /// - /// The local placement handle. - /// - /// - /// The handle. - /// - public static IFCAnyHandle ExportCurtainObjectCommonAsOneBRep(ICollection allSubElements, Element wallElement, - ExporterIFC exporterIFC) + /// Collection of elements contained in the host curtain element. + /// The curtain wall element. + /// The ExporterIFC object. + /// The PlacementSetter object. + /// The local placement handle. + public static void ExportCurtainObjectAsOneEntity(IFCAnyHandle parentHnd, + ICollection allSubElements, Element wallElement, ExporterIFC exporterIFC) { IFCAnyHandle prodDefRep = null; Document document = wallElement.Document; @@ -205,12 +134,11 @@ class CurtainSystemExporter { Element subElem = wallElement.Document.GetElement(subElemId); GeometryElement geomElem = subElem.get_Geometry(geomOptions); - if (geomElem == null) - continue; - - if (alreadyVisited.Contains(subElem.Id)) + if (geomElem == null || alreadyVisited.Contains(subElemId)) + { continue; - alreadyVisited.Add(subElem.Id); + } + alreadyVisited.Add(subElemId); // Export tessellated geometry when IFC4 Reference View is selected @@ -221,7 +149,9 @@ class CurtainSystemExporter if (triFaceSet != null && triFaceSet.Count > 0) { foreach (IFCAnyHandle triFaceSetItem in triFaceSet) + { bodyItems.Add(triFaceSetItem); + } useFallbackBREP = false; // no need to do Brep since it is successful } } @@ -229,9 +159,8 @@ class CurtainSystemExporter else if (ExporterCacheManager.ExportOptionsCache.ExportAs4DesignTransferView) { IFCAnyHandle advancedBRep = BodyExporter.ExportBodyAsAdvancedBrep(exporterIFC, subElem, geomElem); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(advancedBRep)) + if (bodyItems.AddIfNotNull(advancedBRep)) { - bodyItems.Add(advancedBRep); useFallbackBREP = false; // no need to do Brep since it is successful } } @@ -243,64 +172,67 @@ class CurtainSystemExporter IFCAnyHandle outer = IFCInstanceExporter.CreateClosedShell(file, faces); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(outer)) - bodyItems.Add(RepresentationUtil.CreateFacetedBRep(exporterIFC, document, + { + bodyItems.Add(RepresentationUtil.CreateFacetedBRep(exporterIFC, document, false, outer, ElementId.InvalidElementId)); + } } } if (bodyItems.Count == 0) - return prodDefRep; + { + return; + } ElementId catId = CategoryUtil.GetSafeCategoryId(wallElement); IFCAnyHandle shapeRep; // Use tessellated geometry in Reference View if ((ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView || ExporterCacheManager.ExportOptionsCache.ExportAs4General) && !useFallbackBREP) + { shapeRep = RepresentationUtil.CreateTessellatedRep(exporterIFC, wallElement, catId, contextOfItems, bodyItems, null); + } else if (ExporterCacheManager.ExportOptionsCache.ExportAs4DesignTransferView && !useFallbackBREP) + { shapeRep = RepresentationUtil.CreateAdvancedBRepRep(exporterIFC, wallElement, catId, contextOfItems, bodyItems, null); + } else + { shapeRep = RepresentationUtil.CreateBRepRep(exporterIFC, wallElement, catId, contextOfItems, bodyItems); + } if (IFCAnyHandleUtil.IsNullOrHasNoValue(shapeRep)) - return prodDefRep; + { + return; + } - IList shapeReps = new List(); - shapeReps.Add(shapeRep); + IList shapeReps = new List() { shapeRep }; IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, wallElement.get_Geometry(geomOptions), Transform.Identity); if (boundingBoxRep != null) + { shapeReps.Add(boundingBoxRep); + } prodDefRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps); - return prodDefRep; + IFCAnyHandleUtil.SetAttribute(parentHnd, "Representation", prodDefRep); } /// /// Checks if the curtain element can be exported as container. /// - /// - /// It checks if all sub elements to be exported have geometries. - /// - /// - /// Collection of elements contained in the host curtain element. - /// - /// - /// The Revit document. - /// - /// - /// True if it can be exported as container, false otherwise. - /// + /// It checks if all sub elements to be exported have geometries. + /// Collection of elements contained in the host curtain element. + /// The Revit document. + /// True if it can be exported as container, false otherwise. private static bool CanExportCurtainWallAsContainer(ICollection allSubElements, Document document) { Options geomOptions = GeometryUtil.GetIFCExportGeometryOptions(); FilteredElementCollector collector = new FilteredElementCollector(document, allSubElements); - List curtainWallSubElementTypes = new List(); - curtainWallSubElementTypes.Add(typeof(FamilyInstance)); - curtainWallSubElementTypes.Add(typeof(CurtainGridLine)); - curtainWallSubElementTypes.Add(typeof(Wall)); + List curtainWallSubElementTypes = new List() + { typeof(FamilyInstance), typeof(CurtainGridLine), typeof(Wall) }; ElementMulticlassFilter multiclassFilter = new ElementMulticlassFilter(curtainWallSubElementTypes, true); collector.WherePasses(multiclassFilter); @@ -322,16 +254,17 @@ private static bool CanExportCurtainWallAsContainer(ICollection allSu /// Collection of elements contained in the host curtain element. /// The element to be exported. /// The ProductWrapper. - private static void ExportBase(ExporterIFC exporterIFC, ICollection allSubElements, Element element, ProductWrapper wrapper) + private static void ExportBase(ExporterIFC exporterIFC, ICollection allSubElements, Element element, + ProductWrapper wrapper) { - Common.Enums.IFCEntityType elementClassTypeEnum = Common.Enums.IFCEntityType.IfcRoof; - if (element is Wall || element is CurtainSystem || IsLegacyCurtainElement(element)) - elementClassTypeEnum = Common.Enums.IFCEntityType.IfcCurtainWall; - else if (element is RoofBase) - elementClassTypeEnum = Common.Enums.IFCEntityType.IfcRoof; + string ifcEnumType; + IFCExportInfoPair exportType = ExporterUtil.GetProductExportType(exporterIFC, element, out ifcEnumType); - if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) + if (exportType.IsUnKnown || + ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(exportType.ExportInstance)) + { return; + } IFCFile file = exporterIFC.GetFile(); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; @@ -355,23 +288,9 @@ private static void ExportBase(ExporterIFC exporterIFC, ICollection a string objectType = NamingUtil.CreateIFCObjectName(exporterIFC, element); IFCAnyHandle prodRepHnd = null; - IFCAnyHandle elemHnd = null; string elemGUID = GUIDUtil.CreateGUID(element); - if (element is Wall || element is CurtainSystem || IsLegacyCurtainElement(element)) - { - elemHnd = IFCInstanceExporter.CreateCurtainWall(exporterIFC, element, elemGUID, ownerHistory, localPlacement, prodRepHnd, null); - } - else if (element is RoofBase) - { - //need to convert the string to enum - string ifcEnumType = ExporterUtil.GetIFCTypeFromExportTable(exporterIFC, element); - //ifcEnumType = IFCValidateEntry.GetValidIFCPredefinedType(element, ifcEnumType); - elemHnd = IFCInstanceExporter.CreateRoof(exporterIFC, element, elemGUID, ownerHistory, localPlacement, prodRepHnd, ifcEnumType); - } - else - { - return; - } + IFCAnyHandle elemHnd = IFCInstanceExporter.CreateGenericIFCEntity(exportType, + exporterIFC, element, elemGUID, ownerHistory, localPlacement, prodRepHnd); if (IFCAnyHandleUtil.IsNullOrHasNoValue(elemHnd)) return; @@ -379,12 +298,9 @@ private static void ExportBase(ExporterIFC exporterIFC, ICollection a wrapper.AddElement(element, elemHnd, setter, null, true, null); bool canExportCurtainWallAsContainer = CanExportCurtainWallAsContainer(allSubElements, element.Document); - IFCAnyHandle rep = null; if (!canExportCurtainWallAsContainer) { - rep = ExportCurtainObjectCommonAsOneBRep(allSubElements, element, exporterIFC); - if (IFCAnyHandleUtil.IsNullOrHasNoValue(rep)) - return; + ExportCurtainObjectAsOneEntity(elemHnd, allSubElements, element, exporterIFC); } else { @@ -490,16 +406,20 @@ private static void ExportBase(ExporterIFC exporterIFC, ICollection a { // Don't export the Curtain Wall itself, which has no useful geometry; instead export all of the GReps of the // mullions and panels. - CurtainGridSet gridSet = CurtainSystemExporter.GetCurtainGridSet(hostElement); + CurtainGridSet gridSet = GetCurtainGridSet(hostElement); if (gridSet == null) { if (hostElement is Wall) + { ExportLegacyCurtainElement(exporterIFC, hostElement as Wall, productWrapper); + } return; } if (gridSet.Size == 0) + { return; + } ICollection allSubElements = GetSubElements(gridSet, hostElement.Document); ExportBase(exporterIFC, allSubElements, hostElement, productWrapper); @@ -605,7 +525,7 @@ public static bool IsLegacyCurtainWall(Wall wall) if (ex.Message == "The host object is obsolete.") return true; else - throw ex; + throw; } return false; diff --git a/Source/Revit.IFC.Export/Exporter/CurveElementExporter.cs b/Source/Revit.IFC.Export/Exporter/CurveElementExporter.cs index 5382632f..6412a9d9 100644 --- a/Source/Revit.IFC.Export/Exporter/CurveElementExporter.cs +++ b/Source/Revit.IFC.Export/Exporter/CurveElementExporter.cs @@ -72,144 +72,140 @@ private static bool ShouldCurveElementBeExported(CurveElement curveElement) return true; } - /// - /// Exports a curve element to IFC curve annotation. - /// - /// - /// The ExporterIFC object. - /// - /// - /// The curve element to be exported. - /// - /// - /// The geometry element. - /// - /// - /// The ProductWrapper. - /// - public static void ExportCurveElement(ExporterIFC exporterIFC, CurveElement curveElement, GeometryElement geometryElement, - ProductWrapper productWrapper) + private static void ExportCurveBasedElementCommon(ExporterIFC exporterIFC, Element element, + GeometryElement geometryElement, ProductWrapper productWrapper, SketchPlane sketchPlane) { - if (geometryElement == null || !ShouldCurveElementBeExported(curveElement)) - return; - - SketchPlane sketchPlane = curveElement.SketchPlane; - if (sketchPlane == null) - return; + string ifcEnumType = null; + IFCExportInfoPair exportType = + ExporterUtil.GetProductExportType(exporterIFC, element, out ifcEnumType); // Check the intended IFC entity or type name is in the exclude list specified in the UI - IFCEntityType elementClassTypeEnum = IFCEntityType.IfcAnnotation; - if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) + if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(exportType.ExportInstance)) return; - ElementId categoryId = CategoryUtil.GetSafeCategoryId(curveElement); - - string ifcEnumType = null; - if (ExporterCacheManager.ExportOptionsCache.ExportAs4x3) - { - // We only support IfcAnnotation for curves. But if we are exporting to IFC4x3, - // and the user has supplued a predefined type for the IfcAnnotation, we will use it. - IFCExportInfoPair exportType = - ExporterUtil.GetProductExportType(exporterIFC, curveElement, out ifcEnumType); - if (exportType.ExportInstance != IFCEntityType.IfcAnnotation) - ifcEnumType = null; - } + ElementId categoryId = CategoryUtil.GetSafeCategoryId(element); + ElementId sketchPlaneId = sketchPlane?.Id ?? ElementId.InvalidElementId; + // If we are exporting an IfcAnnotation, we will do a little extra work to get the local placement close + // to the sketch plane origin, if there is a sketch plane. We could also do this in the generic case, + // but for now just keeping the existing IfcAnnotation code more or less the same. + bool exportingAnnotation = exportType.ExportInstance == IFCEntityType.IfcAnnotation; IFCFile file = exporterIFC.GetFile(); using (IFCTransaction transaction = new IFCTransaction(file)) { // Check for containment override IFCAnyHandle overrideContainerHnd = null; - ElementId overrideContainerId = ParameterUtil.OverrideContainmentParameter(exporterIFC, curveElement, out overrideContainerHnd); + ElementId overrideContainerId = ParameterUtil.OverrideContainmentParameter(exporterIFC, element, out overrideContainerHnd); - using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, curveElement, null, null, overrideContainerId, overrideContainerHnd)) + using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element, null, null, overrideContainerId, overrideContainerHnd)) { IFCAnyHandle localPlacement = setter.LocalPlacement; - IFCAnyHandle axisPlacement = GeometryUtil.GetRelativePlacementFromLocalPlacement(localPlacement); - - Plane planeSK = sketchPlane.GetPlane(); - XYZ projDir = planeSK.Normal; - XYZ origin = planeSK.Origin; - bool useOffsetTrf = false; - if (projDir.IsAlmostEqualTo(XYZ.BasisZ)) + + bool allowAdvancedCurve = !ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4; + const GeometryUtil.TrimCurvePreference trimCurvePreference = GeometryUtil.TrimCurvePreference.UsePolyLineOrTrim; + + IList curves = new List(); + List curvesFromGeomElem = + GeometryUtil.GetCurvesFromGeometryElement(geometryElement); + foreach (Curve curve in curvesFromGeomElem) { - XYZ offset = XYZ.BasisZ * setter.Offset; - origin -= offset; + curves.AddIfNotNull(GeometryUtil.CreateIFCCurveFromRevitCurve(file, + exporterIFC, curve, allowAdvancedCurve, null, trimCurvePreference, null)); } - else - useOffsetTrf = true; - Transform curveLCS = GeometryUtil.CreateTransformFromPlane(planeSK); - curveLCS.Origin = origin; + HashSet curveSet = new HashSet(curves); + IFCAnyHandle repItemHnd = IFCInstanceExporter.CreateGeometricCurveSet(file, curveSet); - IList curves = null; + IFCAnyHandle curveStyle = file.CreateStyle(exporterIFC, repItemHnd); - if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView) + if (exportingAnnotation) { - Transform trf = null; - if (useOffsetTrf) + CurveAnnotationCache annotationCache = ExporterCacheManager.CurveAnnotationCache; + IFCAnyHandle curveAnno = annotationCache.GetAnnotation(sketchPlaneId, curveStyle); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(curveAnno)) { - XYZ offsetOrig = -XYZ.BasisZ * setter.Offset; - trf = Transform.CreateTranslation(offsetOrig); + AddCurvesToAnnotation(curveAnno, curves); } - - curves = new List(); - //Curve curve = (geometryElement as GeometryObject) as Curve; - List curvesFromGeomElem = GeometryUtil.GetCurvesFromGeometryElement(geometryElement); - foreach (Curve curve in curvesFromGeomElem) + else { - IFCAnyHandle curveHnd = GeometryUtil.CreatePolyCurveFromCurve(exporterIFC, curve, trf); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(curveHnd)) - curves.Add(curveHnd); + curveAnno = CreateCurveAnnotation(exporterIFC, element, + categoryId, Transform.Identity, setter, + localPlacement, repItemHnd, ifcEnumType); + productWrapper.AddAnnotation(curveAnno, setter.LevelInfo, true); + + annotationCache.AddAnnotation(sketchPlaneId, curveStyle, curveAnno); } } else { - IFCGeometryInfo info = IFCGeometryInfo.CreateCurveGeometryInfo(exporterIFC, curveLCS, projDir, false); + string guid = GUIDUtil.CreateGUID(element); + IFCAnyHandle productHandle = CreateAnnotationProductRepresentation(exporterIFC, + file, element, categoryId, repItemHnd); + IFCAnyHandle curveHandle = IFCInstanceExporter.CreateGenericIFCEntity(exportType, + exporterIFC, element, guid, ExporterCacheManager.OwnerHistoryHandle, + localPlacement, productHandle); + productWrapper.AddElement(element, curveHandle, setter.LevelInfo, null, true, exportType); + } + } + transaction.Commit(); + } + } - if (useOffsetTrf) - { - XYZ offsetOrig = -XYZ.BasisZ * setter.Offset; - Transform trf = Transform.CreateTranslation(offsetOrig); - ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, geometryElement, XYZ.Zero, false, trf); - } - else - { - ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, geometryElement, XYZ.Zero, false); - } + /// + /// Exports a curve element to the appropriate IFC entity. + /// + /// The ExporterIFC object. + /// The curve element to be exported. + /// The geometry element. + /// The ProductWrapper. + public static void ExportCurveElement(ExporterIFC exporterIFC, CurveElement curveElement, + GeometryElement geometryElement, ProductWrapper productWrapper) + { + if (geometryElement == null || !ShouldCurveElementBeExported(curveElement)) + return; - curves = info.GetCurves(); - } + SketchPlane sketchPlane = curveElement.SketchPlane; + if (sketchPlane == null) + return; - if (curves.Count != 1) - { - throw new Exception("IFC: expected 1 curve when export curve element."); - } + ExportCurveBasedElementCommon(exporterIFC, curveElement, geometryElement, productWrapper, sketchPlane); + } - HashSet curveSet = new HashSet(curves); - IFCAnyHandle repItemHnd = IFCInstanceExporter.CreateGeometricCurveSet(file, curveSet); + /// + /// Exports a site property line element to the appropriate IFC entity. + /// + /// The ExporterIFC object. + /// The site property line element to be exported. + /// The geometry element. + /// The ProductWrapper. + public static void ExportPropertyLineElement(ExporterIFC exporterIFC, PropertyLine propertyLine, + GeometryElement geometryElement, ProductWrapper productWrapper) + { + if (geometryElement == null) + return; - IFCAnyHandle curveStyle = file.CreateStyle(exporterIFC, repItemHnd); + ExportCurveBasedElementCommon(exporterIFC, propertyLine, geometryElement, productWrapper, null); + } - CurveAnnotationCache annotationCache = ExporterCacheManager.CurveAnnotationCache; - IFCAnyHandle curveAnno = annotationCache.GetAnnotation(sketchPlane.Id, curveStyle); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(curveAnno)) - { - AddCurvesToAnnotation(curveAnno, curves); - } - else - { - curveAnno = CreateCurveAnnotation(exporterIFC, curveElement, - categoryId, sketchPlane.Id, curveLCS, curveStyle, setter, - localPlacement, repItemHnd, ifcEnumType); - productWrapper.AddAnnotation(curveAnno, setter.LevelInfo, true); + static IFCAnyHandle CreateAnnotationProductRepresentation(ExporterIFC exporterIFC, + IFCFile file, Element curveElement, ElementId categoryId, IFCAnyHandle repItemHnd) + { + HashSet bodyItems = new HashSet() { repItemHnd }; + IFCAnyHandle contextOfItems = + ExporterCacheManager.GetOrCreate3DContextHandle(exporterIFC, IFCRepresentationIdentifier.Annotation); - annotationCache.AddAnnotation(sketchPlane.Id, curveStyle, curveAnno); - } - } - transaction.Commit(); - } + // Property lines are 2D plan view objects in Revit, so they should stay as such. + bool is3D = !(curveElement is PropertyLine); + IFCAnyHandle bodyRepHnd = RepresentationUtil.CreateAnnotationSetRep(exporterIFC, + curveElement, categoryId, contextOfItems, bodyItems, is3D); + + if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRepHnd)) + throw new Exception("Failed to create shape representation."); + + List shapes = new List() { bodyRepHnd }; + + return IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapes); } /// @@ -226,24 +222,13 @@ private static bool ShouldCurveElementBeExported(CurveElement curveElement) /// The representation item. /// The handle. static IFCAnyHandle CreateCurveAnnotation(ExporterIFC exporterIFC, Element curveElement, - ElementId categoryId, ElementId sketchPlaneId, Transform curveLCS, - IFCAnyHandle curveStyle, PlacementSetter placementSetter, IFCAnyHandle localPlacement, + ElementId categoryId, Transform curveLCS, + PlacementSetter placementSetter, IFCAnyHandle localPlacement, IFCAnyHandle repItemHnd, string predefinedType) { - HashSet bodyItems = new HashSet() { repItemHnd }; - IFCAnyHandle contextOfItems = - ExporterCacheManager.GetOrCreate3DContextHandle(exporterIFC, IFCRepresentationIdentifier.Annotation); - - IFCAnyHandle bodyRepHnd = RepresentationUtil.CreateAnnotationSetRep(exporterIFC, - curveElement, categoryId, contextOfItems, bodyItems); - - if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRepHnd)) - throw new Exception("Failed to create shape representation."); - - List shapes = new List() { bodyRepHnd }; - IFCFile file = exporterIFC.GetFile(); - IFCAnyHandle prodShapeHnd = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapes); + IFCAnyHandle prodShapeHnd = CreateAnnotationProductRepresentation(exporterIFC, file, + curveElement, categoryId, repItemHnd); XYZ xDir = curveLCS.BasisX; XYZ zDir = curveLCS.BasisZ; XYZ origin = curveLCS.Origin; @@ -272,6 +257,9 @@ private static bool ShouldCurveElementBeExported(CurveElement curveElement) /// The curves. static void AddCurvesToAnnotation(IFCAnyHandle annotation, IList curves) { + if ((curves?.Count ?? 0) == 0) + return; + IFCAnyHandleUtil.ValidateSubTypeOf(annotation, false, IFCEntityType.IfcAnnotation); IFCAnyHandle prodShapeHnd = IFCAnyHandleUtil.GetRepresentation(annotation); @@ -291,7 +279,10 @@ static void AddCurvesToAnnotation(IFCAnyHandle annotation, IList c throw new InvalidOperationException("Expected GeometricSet for IfcAnnotation."); HashSet newElements = IFCAnyHandleUtil.GetAggregateInstanceAttribute>(repItemHnd, "Elements"); - newElements.Add(curves[0]); + foreach (IFCAnyHandle curve in curves) + { + newElements.Add(curve); + } IFCAnyHandleUtil.SetAttribute(repItemHnd, "Elements", newElements); } } diff --git a/Source/Revit.IFC.Export/Exporter/Exporter.cs b/Source/Revit.IFC.Export/Exporter/Exporter.cs index 27732f69..615e7659 100644 --- a/Source/Revit.IFC.Export/Exporter/Exporter.cs +++ b/Source/Revit.IFC.Export/Exporter/Exporter.cs @@ -38,6 +38,7 @@ using Revit.IFC.Export.Properties; using System.Reflection; using Autodesk.Revit.DB.Steel; +using Autodesk.Revit.DB.Analysis; namespace Revit.IFC.Export.Exporter { @@ -181,6 +182,8 @@ public void ExportIFC(Document document, ExporterIFC exporterIFC, View filterVie try { + ExporterCacheManager.ExporterIFC = exporterIFC; + IFCAnyHandleUtil.IFCStringTooLongWarn += (_1) => { document.Application.WriteJournalComment(_1, true); }; IFCDataUtil.IFCStringTooLongWarn += (_1) => { document.Application.WriteJournalComment(_1, true); }; @@ -296,7 +299,7 @@ protected void ExportAdvanceSteelElements(ExporterIFC exporterIFC, Autodesk.Revi if (File.Exists(Path.GetDirectoryName(dllPath) + @"\Autodesk.SteelConnections.ASIFC.dll")) assembly = Assembly.LoadFrom(Path.GetDirectoryName(dllPath) + @"\Autodesk.SteelConnections.ASIFC.dll"); else - assembly = Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory + @"\Addins\SteelConnections\Autodesk.SteelConnections.ASIFC.dll"); + assembly = Assembly.LoadFrom(Path.Combine(AppContext.BaseDirectory, @"Addins\SteelConnections\Autodesk.SteelConnections.ASIFC.dll")); if (assembly != null) { @@ -378,6 +381,21 @@ private bool SpatialElementInSectionBox(BoundingBoxXYZ sectionBox, Element eleme return GeometryUtil.BoundingBoxesOverlap(elementBBox, sectionBox); } + private bool NeedBuilding() + { + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(ExporterCacheManager.BuildingHandle)) + { + return false; + } + + if (IFCAnyHandleUtil.IsNullOrHasNoValue(ExporterCacheManager.SiteHandle)) + { + return true; + } + + return ExporterCacheManager.ExportOptionsCache.ExportLinkedFileAs == LinkedFileExportAs.ExportSameSite; + } + protected void ExportSpatialElements(ExporterIFC exporterIFC, Document document) { // Create IfcSite first here using the first visible TopographySurface if any, if not create a default one. @@ -409,11 +427,10 @@ protected void ExportSpatialElements(ExporterIFC exporterIFC, Document document) } // Create IfcBuilding first here - if (IFCAnyHandleUtil.IsNullOrHasNoValue(ExporterCacheManager.BuildingHandle) && IFCAnyHandleUtil.IsNullOrHasNoValue(ExporterCacheManager.SiteHandle)) + if (NeedBuilding()) { - IFCAnyHandle buildingPlacement = CreateBuildingPlacement(exporterIFC.GetFile()); - IFCAnyHandle buildingHnd = CreateBuildingFromProjectInfo(exporterIFC, document, buildingPlacement); - ExporterCacheManager.BuildingHandle = buildingHnd; + IFCAnyHandle facilityPlacement = CreateBuildingPlacement(exporterIFC.GetFile()); + IFCAnyHandle facilityHnd = CreateFacilityFromProjectInfo(exporterIFC, document, facilityPlacement, true); } ExportOptionsCache exportOptionsCache = ExporterCacheManager.ExportOptionsCache; @@ -655,7 +672,7 @@ protected virtual bool CanExportElement(ExporterIFC exporterIFC, Autodesk.Revit. { } } - return ElementFilteringUtil.CanExportElement(exporterIFC, element, false); + return ElementFilteringUtil.CanExportElement(element, false); } /// @@ -691,11 +708,6 @@ public virtual bool ExportElement(ExporterIFC exporterIFC, Element element) { using (ProductWrapper productWrapper = ProductWrapper.Create(exporterIFC, true)) { - if (element.AssemblyInstanceId != null && element.AssemblyInstanceId != ElementId.InvalidElementId) - { - Element assemblyElem = element.Document.GetElement(element.AssemblyInstanceId); - ExportElementImpl(exporterIFC, assemblyElem, productWrapper); - } ExportElementImpl(exporterIFC, element, productWrapper); ExporterUtil.ExportRelatedProperties(exporterIFC, element, productWrapper); } @@ -917,6 +929,11 @@ public virtual void ExportElementImpl(ExporterIFC exporterIFC, Element element, PipeInsulation pipeInsulation = element as PipeInsulation; PipeInsulationExporter.ExportPipeInsulation(exporterIFC, pipeInsulation, geomElem, productWrapper); } + else if (element is PropertyLine) + { + PropertyLine propertyLine = element as PropertyLine; + CurveElementExporter.ExportPropertyLineElement(exporterIFC, propertyLine, geomElem, productWrapper); + } else if (element is Railing) { if (ExporterCacheManager.RailingCache.Contains(element.Id)) @@ -1022,7 +1039,7 @@ public virtual void ExportElementImpl(ExporterIFC exporterIFC, Element element, // to have this check before the (element is HostObject check. exported = ProxyElementExporter.Export(exporterIFC, element, geomElem, productWrapper, exportType); } - else if (elementIsFabricationPart || (element is HostObject) || (element is DirectShape)) + else if (elementIsFabricationPart || (element is HostObject) || (element is DirectShape) || (element is MassLevelData)) { exported = GenericElementExporter.ExportElement(exporterIFC, element, geomElem, productWrapper); } @@ -1031,10 +1048,14 @@ public virtual void ExportElementImpl(ExporterIFC exporterIFC, Element element, { // For ducts and pipes, we will add a IfcRelCoversBldgElements during the end of export. if (element is Duct || element is Pipe) - ExporterCacheManager.MEPCache.CoveredElementsCache.Add(element.Id); + { + ExporterCacheManager.MEPCache.CoveredElementsCache[element.Id] = element.Category?.Id ?? ElementId.InvalidElementId; + } // For cable trays and conduits, we might create systems during the end of export. if (element is CableTray || element is Conduit) + { ExporterCacheManager.MEPCache.CableElementsCache.Add(element.Id); + } } } @@ -1184,6 +1205,42 @@ private void BeginLinkedDocumentExport(ExporterIFC exporterIFC, Document documen BeginDocumentExportCommon(exporterIFC, document); } + private IFCAnyHandle CreateFacilityPart(ExporterIFC exporterIFC, Level level, string objectType, + IFCAnyHandle objectPlacement, IFCElementComposition compositionType, double elevation, string predefinedType) + { + IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; + + if (!ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4x3) + { + switch (ExporterCacheManager.ExportOptionsCache.FacilityType) + { + case KnownFacilityTypes.Bridge: + { + return IFCInstanceExporter.CreateBridgePart(exporterIFC, level, ownerHistory, objectType, + objectPlacement, compositionType, predefinedType); + } + case KnownFacilityTypes.MarineFacility: + { + return IFCInstanceExporter.CreateMarinePart(exporterIFC, level, ownerHistory, objectType, + objectPlacement, compositionType); + } + case KnownFacilityTypes.Railway: + { + return IFCInstanceExporter.CreateRailwayPart(exporterIFC, level, ownerHistory, objectType, + objectPlacement, compositionType); + } + case KnownFacilityTypes.Road: + { + return IFCInstanceExporter.CreateRoadPart(exporterIFC, level, ownerHistory, objectType, + objectPlacement, compositionType); + } + } + } + + return IFCInstanceExporter.CreateBuildingStorey(exporterIFC, level, + ownerHistory, objectType, objectPlacement, compositionType, elevation); + } + /// /// Initializes the common properties at the beginning of the export process. /// @@ -1209,10 +1266,8 @@ private void BeginDocumentExportCommon(ExporterIFC exporterIFC, Document documen bool exportBuilding = ExportBuilding(allLevels); // Skip Building if there is no Storey to be exported - if (exportBuilding) - { - CreateBuildingFromProjectInfo(exporterIFC, document, buildingPlacement); - + if (CreateFacilityFromProjectInfo(exporterIFC, document, buildingPlacement, exportBuilding) != null) + { IList unassignedBaseLevels = new List(); double lengthScale = UnitUtil.ScaleLengthForRevitAPI(); @@ -1283,25 +1338,32 @@ private void BeginDocumentExportCommon(ExporterIFC exporterIFC, Document documen IFCAnyHandle placement = ExporterUtil.CreateLocalPlacement(file, buildingPlacement, orig, null, null); string bsObjectType = NamingUtil.GetObjectTypeOverride(level, null); IFCElementComposition ifcComposition = LevelUtil.GetElementCompositionTypeOverride(level); - IFCAnyHandle buildingStorey = IFCInstanceExporter.CreateBuildingStorey(exporterIFC, level, ExporterCacheManager.OwnerHistoryHandle, - bsObjectType, placement, ifcComposition, elevation); + + // IFC4.3 questions: How do we best support predefined type for IfcFacilityParts other than + // IfcBuildingStoreys? + // Are nested IfcFacilityParts more common/needed, or is that an OK limitation for Revit to only + // have one level supported? + // Do we need to sort by elevation, even though elevation is only for building stories? + string predefinedType = null; + IFCAnyHandle facilityPart = CreateFacilityPart(exporterIFC, level, bsObjectType, placement, + ifcComposition, elevation, predefinedType); // Create classification reference when level has classification field name assigned to it - ClassificationUtil.CreateClassification(exporterIFC, file, level, buildingStorey); + ClassificationUtil.CreateClassification(exporterIFC, file, level, facilityPart); - prevBuildingStorey = buildingStorey; + prevBuildingStorey = facilityPart; prevPlacement = placement; prevHeight = height; prevElev = elev; - levelInfo = IFCLevelInfo.Create(buildingStorey, placement, height, elev, lengthScale, true); + levelInfo = IFCLevelInfo.Create(facilityPart, placement, height, elev, lengthScale, true); ExporterCacheManager.LevelInfoCache.AddLevelInfo(exporterIFC, level.Id, levelInfo, true); // if we have coincident levels, add buildingstories for them but use the old handle. for (int jj = 0; jj < coincidentLevels.Count; jj++) { level = allLevels[ii + jj + 1]; - levelInfo = IFCLevelInfo.Create(buildingStorey, placement, height, elev, lengthScale, true); + levelInfo = IFCLevelInfo.Create(facilityPart, placement, height, elev, lengthScale, true); ExporterCacheManager.LevelInfoCache.AddLevelInfo(exporterIFC, level.Id, levelInfo, true); } @@ -1320,9 +1382,7 @@ private void GetElementHandles(ICollection ids, ISet ha { foreach (ElementId id in ids) { - IFCAnyHandle handle = ExporterCacheManager.ElementToHandleCache.Find(id); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(handle)) - handles.Add(handle); + handles.AddIfNotNull(ExporterCacheManager.ElementToHandleCache.Find(id)); } } } @@ -1398,9 +1458,8 @@ private void CreatePresentationLayerAssignments(ExporterIFC exporterIFC, IFCFile ISet validHandles = new HashSet(); foreach (IFCAnyHandle handle in presentationLayerSet.Value) { - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(handle)) + if (validHandles.AddIfNotNull(handle)) { - validHandles.Add(handle); assignedRepresentations.Add(handle); } } @@ -1493,8 +1552,10 @@ private void EndHostDocumentExport(ExporterIFC exporterIFC, Document document) using (IFCTransaction transaction = new IFCTransaction(file)) { // Relate Ducts and Pipes to their coverings (insulations and linings) - foreach (ElementId ductOrPipeId in ExporterCacheManager.MEPCache.CoveredElementsCache) + foreach (KeyValuePair ductOrPipe in ExporterCacheManager.MEPCache.CoveredElementsCache) { + ElementId ductOrPipeId = ductOrPipe.Key; + IFCAnyHandle ductOrPipeHandle = ExporterCacheManager.MEPCache.Find(ductOrPipeId); if (IFCAnyHandleUtil.IsNullOrHasNoValue(ductOrPipeHandle)) continue; @@ -1503,8 +1564,11 @@ private void EndHostDocumentExport(ExporterIFC exporterIFC, Document document) try { - ICollection liningIds = InsulationLiningBase.GetLiningIds(document, ductOrPipeId); - GetElementHandles(liningIds, coveringHandles); + if (FamilyInstanceExporter.CategoryCanHaveLining(ductOrPipe.Value)) + { + ICollection liningIds = InsulationLiningBase.GetLiningIds(document, ductOrPipeId); + GetElementHandles(liningIds, coveringHandles); + } } catch { @@ -1561,28 +1625,24 @@ private void EndHostDocumentExport(ExporterIFC exporterIFC, Document document) IFCAnyHandle projectHandle = ExporterCacheManager.ProjectHandle; IFCAnyHandle siteHandle = ExporterCacheManager.SiteHandle; - IFCAnyHandle buildingHandle = ExporterCacheManager.BuildingHandle; + IFCAnyHandle facilityHandle = ExporterCacheManager.BuildingHandle; bool projectHasSite = !IFCAnyHandleUtil.IsNullOrHasNoValue(siteHandle); - bool projectHasBuilding = !IFCAnyHandleUtil.IsNullOrHasNoValue(buildingHandle); + bool projectHasFacility = !IFCAnyHandleUtil.IsNullOrHasNoValue(facilityHandle); - IFCAnyHandle siteOrbuildingHnd = siteHandle; - - if (!projectHasSite) + if (!projectHasSite && !projectHasFacility) { - if (!projectHasBuilding) - { - // if at this point the buildingHnd is null, which means that the model does not - // have Site nor any Level assigned to the BuildingStorey, create the IfcBuilding - // as the general container for all the elements (should be backward compatible). - IFCAnyHandle buildingPlacement = CreateBuildingPlacement(file); - buildingHandle = CreateBuildingFromProjectInfo(exporterIFC, document, buildingPlacement); - ExporterCacheManager.BuildingHandle = buildingHandle; - projectHasBuilding = true; - } - siteOrbuildingHnd = buildingHandle; + // if at this point the facilityHnd is null, which means that the model does not + // have Site nor any Level assigned to the FacilityPart, create the IfcFacility + // as the general container for all the elements (should be backward compatible). + IFCAnyHandle facilityPlacement = CreateBuildingPlacement(file); + facilityHandle = CreateFacilityFromProjectInfo(exporterIFC, document, facilityPlacement, true); + ExporterCacheManager.BuildingHandle = facilityHandle; + projectHasFacility = true; } + IFCAnyHandle siteOrFacilityHnd = projectHasFacility ? facilityHandle : siteHandle; + // Last chance to create the building handle was just above. if (projectHasSite) { @@ -1594,12 +1654,12 @@ private void EndHostDocumentExport(ExporterIFC exporterIFC, Document document) ExporterCacheManager.ContainmentCache.AddRelation(projectHandle, siteHandle); } - if (projectHasBuilding) + if (projectHasFacility) { - // assoc. site to the building. - ExporterCacheManager.ContainmentCache.AddRelation(siteHandle, buildingHandle); + // assoc. site to the facility. + ExporterCacheManager.ContainmentCache.AddRelation(siteHandle, facilityHandle); - IFCAnyHandle buildingPlacement = IFCAnyHandleUtil.GetObjectPlacement(buildingHandle); + IFCAnyHandle buildingPlacement = IFCAnyHandleUtil.GetObjectPlacement(facilityHandle); IFCAnyHandle relPlacement = IFCAnyHandleUtil.GetObjectPlacement(siteHandle); GeometryUtil.SetPlacementRelTo(buildingPlacement, relPlacement); } @@ -1607,8 +1667,8 @@ private void EndHostDocumentExport(ExporterIFC exporterIFC, Document document) else { // relate building and project if no site - if (projectHasBuilding) - ExporterCacheManager.ContainmentCache.AddRelation(projectHandle, buildingHandle); + if (projectHasFacility) + ExporterCacheManager.ContainmentCache.AddRelation(projectHandle, facilityHandle); } // relate assembly elements to assemblies @@ -1688,7 +1748,7 @@ private void EndHostDocumentExport(ExporterIFC exporterIFC, Document document) // Relate levels and products. This may create new orphaned elements, so deal with those next. RelateLevels(exporterIFC, document); - IFCAnyHandle defContainerObjectPlacement = IFCAnyHandleUtil.GetObjectPlacement(siteOrbuildingHnd); + IFCAnyHandle defContainerObjectPlacement = IFCAnyHandleUtil.GetObjectPlacement(siteOrFacilityHnd); Transform defContainerTrf = ExporterUtil.GetTotalTransformFromLocalPlacement(defContainerObjectPlacement); Transform defContainerInvTrf = defContainerTrf.Inverse; @@ -1705,40 +1765,40 @@ private void EndHostDocumentExport(ExporterIFC exporterIFC, Document document) ElementId elementId = ExporterCacheManager.HandleToElementCache.Find(elemHnd); Element elem = document.GetElement(elementId); - // if there is override, use the override otherwise use default from site + // if there is override, use the override otherwise use default IFCAnyHandle overrideContainer = null; ParameterUtil.OverrideContainmentParameter(exporterIFC, elem, out overrideContainer); bool containerIsSite = projectHasSite; - bool containerIsBuilding = projectHasBuilding; + bool containerIsFacility = projectHasFacility; IFCAnyHandle containerObjectPlacement = null; if (!IFCAnyHandleUtil.IsNullOrHasNoValue(overrideContainer)) { containerObjectPlacement = IFCAnyHandleUtil.GetObjectPlacement(overrideContainer); containerIsSite = IFCAnyHandleUtil.IsTypeOf(overrideContainer, IFCEntityType.IfcSite); - containerIsBuilding = !containerIsSite && + containerIsFacility = !containerIsSite && IFCAnyHandleUtil.IsTypeOf(overrideContainer, IFCEntityType.IfcBuilding); } else { - // Default behavior (generally site). + // Default behavior (generally facility). containerObjectPlacement = defContainerObjectPlacement; } - if (containerIsSite) - relatedElementSetForSite.Add(elemHnd); - else if (containerIsBuilding) + if (containerIsFacility) relatedElementSetForBuilding.Add(elemHnd); - + else if (containerIsSite) + relatedElementSetForSite.Add(elemHnd); + UpdateLocalPlacementForElement(elemHnd, file, containerObjectPlacement, null); } - if (relatedElementSetForBuilding.Count > 0 && projectHasBuilding) + if (relatedElementSetForBuilding.Count > 0 && projectHasFacility) { string guid = GUIDUtil.CreateSubElementGUID(projectInfo, (int)IFCProjectSubElements.RelContainedInBuildingSpatialStructure); IFCInstanceExporter.CreateRelContainedInSpatialStructure(file, guid, - ownerHistory, null, null, relatedElementSetForBuilding, buildingHandle); + ownerHistory, null, null, relatedElementSetForBuilding, facilityHandle); } if (relatedElementSetForSite.Count > 0 && projectHasSite) @@ -1760,9 +1820,9 @@ private void EndHostDocumentExport(ExporterIFC exporterIFC, Document document) foreach (IFCAnyHandle indivSpace in buildingSpaces) { bool containerIsSite = projectHasSite; - bool containerIsBuilding = projectHasBuilding; + bool containerIsBuilding = projectHasFacility; - // if there is override, use the override otherwise use default from site + // if there is override, use the override otherwise use default IFCAnyHandle overrideContainer = null; ParameterUtil.OverrideSpaceContainmentParameter(exporterIFC, document, indivSpace, out overrideContainer); IFCAnyHandle containerObjectPlacement = null; @@ -1779,22 +1839,22 @@ private void EndHostDocumentExport(ExporterIFC exporterIFC, Document document) } else { - // Default behavior (generally site). + // Default behavior (generally facility). containerObjectPlacement = defContainerObjectPlacement; containerInvTrf = defContainerInvTrf; } - if (containerIsSite) - relatedElementSetForSite.Add(indivSpace); - else if (containerIsBuilding) + if (containerIsBuilding) relatedElementSetForBuilding.Add(indivSpace); + else if (containerIsSite) + relatedElementSetForSite.Add(indivSpace); UpdateLocalPlacementForElement(indivSpace, file, containerObjectPlacement, containerInvTrf); } if (relatedElementSetForBuilding.Count > 0) { - ExporterCacheManager.ContainmentCache.AddRelations(buildingHandle, null, relatedElementSetForBuilding); + ExporterCacheManager.ContainmentCache.AddRelations(facilityHandle, null, relatedElementSetForBuilding); } if (relatedElementSetForSite.Count > 0) @@ -1816,8 +1876,8 @@ private void EndHostDocumentExport(ExporterIFC exporterIFC, Document document) // These elements are created internally, but we allow custom property sets for them. Create them here. using (ProductWrapper productWrapper = ProductWrapper.Create(exporterIFC, true)) { - if (projectHasBuilding) - productWrapper.AddBuilding(projectInfo, buildingHandle); + if (projectHasFacility) + productWrapper.AddBuilding(projectInfo, facilityHandle); if (projectInfo != null) ExporterUtil.ExportRelatedProperties(exporterIFC, projectInfo, productWrapper); } @@ -2101,10 +2161,11 @@ private void EndHostDocumentExport(ExporterIFC exporterIFC, Document document) relGuid, classificationReference.Key, null, zoneHnds); } - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(zoneInfo.ZoneCommonProperySetHandle)) + IFCAnyHandle zoneCommonProperySetHandle = zoneInfo.CreateZoneCommonPSetData(file); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(zoneCommonProperySetHandle)) { ExporterUtil.CreateRelDefinesByProperties(file, - ownerHistory, null, null, zoneHnds, zoneInfo.ZoneCommonProperySetHandle); + ownerHistory, null, null, zoneHnds, zoneCommonProperySetHandle); } string groupName = zoneInfo.GroupName; @@ -2120,20 +2181,6 @@ private void EndHostDocumentExport(ExporterIFC exporterIFC, Document document) } } - // Create RelAssociatesClassifications. - foreach (var relAssociatesInfo in ExporterCacheManager.ClassificationCache.ClassificationRelations) - { - if (IFCAnyHandleUtil.IsNullOrHasNoValue(relAssociatesInfo.Key)) - continue; - - IFCInstanceExporter.CreateRelAssociatesClassification(file, - relAssociatesInfo.Value.GlobalId, ownerHistory, - relAssociatesInfo.Value.Name, - relAssociatesInfo.Value.Description, - relAssociatesInfo.Value.RelatedObjects, - relAssociatesInfo.Key); - } - // now create any zone groups. string relAssignsToZoneGroupName = "Zone Group Assignment"; foreach (KeyValuePair> zoneGroup in zoneGroups) @@ -2192,9 +2239,9 @@ private void EndHostDocumentExport(ExporterIFC exporterIFC, Document document) } // Create systems. - ExportCachedSystem(exporterIFC, document, file, ExporterCacheManager.SystemsCache.BuiltInSystemsCache, ownerHistory, buildingHandle, projectHasBuilding, false); - ExportCachedSystem(exporterIFC, document, file, ExporterCacheManager.SystemsCache.ElectricalSystemsCache, ownerHistory, buildingHandle, projectHasBuilding, true); - ExportCableTraySystem(document, file, ExporterCacheManager.MEPCache.CableElementsCache, ownerHistory, buildingHandle, projectHasBuilding); + ExportCachedSystem(exporterIFC, document, file, ExporterCacheManager.SystemsCache.BuiltInSystemsCache, ownerHistory, facilityHandle, projectHasFacility, false); + ExportCachedSystem(exporterIFC, document, file, ExporterCacheManager.SystemsCache.ElectricalSystemsCache, ownerHistory, facilityHandle, projectHasFacility, true); + ExportCableTraySystem(document, file, ExporterCacheManager.MEPCache.CableElementsCache, ownerHistory, facilityHandle, projectHasFacility); // Add presentation layer assignments - this is in addition to those created internally. // Any representation in this list will override any internal assignment. @@ -2215,6 +2262,20 @@ private void EndHostDocumentExport(ExporterIFC exporterIFC, Document document) } } + // Create RelAssociatesClassifications. + foreach (var relAssociatesInfo in ExporterCacheManager.ClassificationCache.ClassificationRelations) + { + if (IFCAnyHandleUtil.IsNullOrHasNoValue(relAssociatesInfo.Key)) + continue; + + IFCInstanceExporter.CreateRelAssociatesClassification(file, + relAssociatesInfo.Value.GlobalId, ownerHistory, + relAssociatesInfo.Value.Name, + relAssociatesInfo.Value.Description, + relAssociatesInfo.Value.RelatedObjects, + relAssociatesInfo.Key); + } + // Delete handles that are marked for removal foreach (IFCAnyHandle handleToDel in ExporterCacheManager.HandleToDeleteCache) { @@ -2244,6 +2305,10 @@ private void EndHostDocumentExport(ExporterIFC exporterIFC, Document document) if (ExporterCacheManager.ExportOptionsCache.PropertySetOptions.ExportMaterialPsets) MaterialPropertiesUtil.ExportMaterialProperties(file, exporterIFC); + // Create unit assignement + IFCAnyHandle units = IFCInstanceExporter.CreateUnitAssignment(file, UnitMappingUtil.GetUnitsToAssign()); + ExporterCacheManager.ProjectHandle.SetAttribute("UnitsInContext", units); + // Allow native code to remove some unused handles and clear internal caches. ExporterIFCUtils.EndExportInternal(exporterIFC); transaction.Commit(); @@ -2252,6 +2317,8 @@ private void EndHostDocumentExport(ExporterIFC exporterIFC, Document document) private class IFCFileDocumentInfo { + public string ContentGUIDString { get; private set; } = null; + public string VersionGUIDString { get; private set; } = null; public int NumberOfSaves { get; private set; } = 0; @@ -2279,11 +2346,12 @@ public IFCFileDocumentInfo(Document document) ExportOptionsCache exportOptionsCache = ExporterCacheManager.ExportOptionsCache; + ContentGUIDString = document?.CreationGUID.ToString() ?? string.Empty; VersionGUIDString = documentVersion?.VersionGUID.ToString() ?? string.Empty; NumberOfSaves = documentVersion?.NumberOfSaves ?? 0; ProjectNumber = projectInfo?.Number ?? string.Empty; - ProjectName = projectInfo?.Name ?? exportOptionsCache.FileName; + ProjectName = projectInfo?.Name ?? exportOptionsCache.FileNameOnly; ProjectStatus = projectInfo?.Status ?? string.Empty; VersionName = application?.VersionName; @@ -2305,8 +2373,7 @@ public IFCFileDocumentInfo(Document document) // When exporting Link, the relative position of the Link instance in the model needs to be transformed with // the offset from the main model site transform SiteTransformBasis transformBasis = ExporterCacheManager.ExportOptionsCache.SiteTransformation; - bool useSitePlacement = canUseSitePlacement && (transformBasis != SiteTransformBasis.Internal && - transformBasis != SiteTransformBasis.InternalInTN); + bool useSitePlacement = canUseSitePlacement && (transformBasis != SiteTransformBasis.Internal); bool useRotation = transformBasis == SiteTransformBasis.InternalInTN || transformBasis == SiteTransformBasis.ProjectInTN || transformBasis == SiteTransformBasis.Shared || @@ -2315,7 +2382,7 @@ public IFCFileDocumentInfo(Document document) new Transform(CoordReferenceInfo.MainModelCoordReferenceOffset ?? Transform.Identity); XYZ siteOffset = useSitePlacement ? sitePl.Origin : XYZ.Zero; - if (useRotation) + if (useRotation && useSitePlacement) { // For those that oriented in the TN, a rotation is needed to compute a correct offset in TN orientation Transform rotationTrfAtInternal = Transform.CreateRotationAtPoint(XYZ.BasisZ, CoordReferenceInfo.MainModelTNAngle, XYZ.Zero); @@ -2327,7 +2394,7 @@ public IFCFileDocumentInfo(Document document) } sitePl.Origin = XYZ.Zero; linkTrf.Origin = XYZ.Zero; - Transform linkTotTrf = sitePl.Multiply(linkTrf); + Transform linkTotTrf = useSitePlacement ? sitePl.Multiply(linkTrf) : linkTrf; linkTotTrf.Origin = siteOffset; IFCAnyHandle relativePlacement = ExporterUtil.CreateAxis2Placement3D(file, @@ -2396,8 +2463,8 @@ private void WriteIFCFile(IFCFile file, IFCFileDocumentInfo ifcFileDocumentInfo) } - string versionLine = string.Format("RevitIdentifiers [VersionGUID: {0}, NumberOfSaves: {1}]", - ifcFileDocumentInfo.VersionGUIDString, ifcFileDocumentInfo.NumberOfSaves); + string versionLine = string.Format("RevitIdentifiers [ContentGUID: {0}, VersionGUID: {1}, NumberOfSaves: {2}]", + ifcFileDocumentInfo.ContentGUIDString, ifcFileDocumentInfo.VersionGUIDString, ifcFileDocumentInfo.NumberOfSaves); descriptions.Add(versionLine); @@ -2449,14 +2516,14 @@ private void WriteIFCFile(IFCFile file, IFCFileDocumentInfo ifcFileDocumentInfo) if (fHItem.Authorization == null) fHItem.Authorization = string.Empty; - IFCInstanceExporter.CreateFileName(file, projectNumber, author, organization, + IFCInstanceExporter.CreateFileName(file, exportOptionsCache.FileNameOnly, author, organization, ifcFileDocumentInfo.VersionName, versionInfos, fHItem.Authorization); transaction.Commit(); IFCFileWriteOptions writeOptions = new IFCFileWriteOptions() { - FileName = exportOptionsCache.FileName, + FileName = exportOptionsCache.FullFileName, FileFormat = exportOptionsCache.IFCFileFormat }; @@ -2846,13 +2913,16 @@ private void CreateProject(ExporterIFC exporterIFC, Document doc, IFCAnyHandle a List prefixTitles; List suffixTitles; - string author = String.Empty; + string author = string.Empty; + bool hasPotentialLastUser = false; + ProjectInfo projectInfo = doc.ProjectInformation; if (projectInfo != null) { try { author = projectInfo.Author; + hasPotentialLastUser = !string.IsNullOrWhiteSpace(author); } catch (Autodesk.Revit.Exceptions.InvalidOperationException) { @@ -2888,12 +2958,11 @@ private void CreateProject(ExporterIFC exporterIFC, Document doc, IFCAnyHandle a } else { - IFCAnyHandle telecomAddress = GetTelecomAddressFromExtStorage(file); IList telecomAddresses = null; + IFCAnyHandle telecomAddress = GetTelecomAddressFromExtStorage(file); if (telecomAddress != null) { - telecomAddresses = new List(); - telecomAddresses.Add(telecomAddress); + telecomAddresses = new List() { telecomAddress }; } person = IFCInstanceExporter.CreatePerson(file, null, familyName, givenName, middleNames, @@ -2917,8 +2986,11 @@ private void CreateProject(ExporterIFC exporterIFC, Document doc, IFCAnyHandle a } IFCAnyHandle owningUser = IFCInstanceExporter.CreatePersonAndOrganization(file, person, organization, null); + IFCAnyHandle lastModifyingUser = hasPotentialLastUser && ExporterCacheManager.ExportOptionsCache.OwnerHistoryLastModified + ? owningUser : null; + ownerHistory = IFCInstanceExporter.CreateOwnerHistory(file, owningUser, application, null, - Toolkit.IFCChangeAction.NoChange, null, null, null, creationDate); + IFCChangeAction.NoChange, null, lastModifyingUser, null, creationDate); exporterIFC.SetOwnerHistoryHandle(ownerHistory); // For use by native code only. ExporterCacheManager.OwnerHistoryHandle = ownerHistory; @@ -2926,7 +2998,8 @@ private void CreateProject(ExporterIFC exporterIFC, Document doc, IFCAnyHandle a // Getting contact information from Revit extensible storage that COBie extension tool creates GetCOBieContactInfo(file, doc); - IFCAnyHandle units = CreateDefaultUnits(exporterIFC, doc); + UnitMappingUtil.CreateCobieUnits(); + IList directionRatios = null; HashSet repContexts = CreateContextInformation(exporterIFC, doc, out directionRatios); @@ -2958,7 +3031,7 @@ private void CreateProject(ExporterIFC exporterIFC, Document doc, IFCAnyHandle a string projectGUID = GUIDUtil.CreateProjectLevelGUID(doc, GUIDUtil.ProjectLevelGUIDType.Project); IFCAnyHandle projectHandle = IFCInstanceExporter.CreateProject(exporterIFC, projectInfo, projectGUID, ownerHistory, - projectName, projectDescription, projectLongName, projectPhase, repContexts, units); + projectName, projectDescription, projectLongName, projectPhase, repContexts, null); ExporterCacheManager.ProjectHandle = projectHandle; @@ -3191,1308 +3264,175 @@ static public IFCAnyHandle CreateIFCAddress(IFCFile file, Document document, Pro return postalAddress; } + + /// + /// Creates the global direction and sets the cardinal directions in 3D. + /// + /// The IFC exporter object. + private void CreateGlobalDirection(ExporterIFC exporterIFC) + { + // Note that we do not use the ExporterUtil.CreateDirection functions below, as they try + // to match the input XYZ to one of the "global" directions that we are creating below. + IFCAnyHandle xDirPos = null; + IFCAnyHandle xDirNeg = null; + IFCAnyHandle yDirPos = null; + IFCAnyHandle yDirNeg = null; + IFCAnyHandle zDirPos = null; + IFCAnyHandle zDirNeg = null; + + IFCFile file = exporterIFC.GetFile(); + IList xxp = new List(); + xxp.Add(1.0); xxp.Add(0.0); xxp.Add(0.0); + xDirPos = IFCInstanceExporter.CreateDirection(file, xxp); + + IList xxn = new List(); + xxn.Add(-1.0); xxn.Add(0.0); xxn.Add(0.0); + xDirNeg = IFCInstanceExporter.CreateDirection(file, xxn); + + IList yyp = new List(); + yyp.Add(0.0); yyp.Add(1.0); yyp.Add(0.0); + yDirPos = IFCInstanceExporter.CreateDirection(file, yyp); + + IList yyn = new List(); + yyn.Add(0.0); yyn.Add(-1.0); yyn.Add(0.0); + yDirNeg = IFCInstanceExporter.CreateDirection(file, yyn); + + IList zzp = new List(); + zzp.Add(0.0); zzp.Add(0.0); zzp.Add(1.0); + zDirPos = IFCInstanceExporter.CreateDirection(file, zzp); + + IList zzn = new List(); + zzn.Add(0.0); zzn.Add(0.0); zzn.Add(-1.0); + zDirNeg = IFCInstanceExporter.CreateDirection(file, zzn); + + ExporterIFCUtils.SetGlobal3DDirectionHandles(true, xDirPos, yDirPos, zDirPos); + ExporterIFCUtils.SetGlobal3DDirectionHandles(false, xDirNeg, yDirNeg, zDirNeg); + } - private IFCAnyHandle CreateSIUnit(IFCFile file, ForgeTypeId specTypeId, IFCUnit ifcUnitType, IFCSIUnitName unitName, IFCSIPrefix? prefix, ForgeTypeId unitTypeId) + /// + /// Creates the global direction and sets the cardinal directions in 2D. + /// + /// The IFC exporter object. + private void CreateGlobalDirection2D(ExporterIFC exporterIFC) { - IFCAnyHandle siUnit = IFCInstanceExporter.CreateSIUnit(file, ifcUnitType, prefix, unitName); - if (specTypeId != null && unitTypeId != null) - { - double scaleFactor = UnitUtils.ConvertFromInternalUnits(1.0, unitTypeId); - ExporterCacheManager.UnitsCache.AddUnit(specTypeId, siUnit, scaleFactor, 0.0); - } + IFCAnyHandle xDirPos2D = null; + IFCAnyHandle xDirNeg2D = null; + IFCAnyHandle yDirPos2D = null; + IFCAnyHandle yDirNeg2D = null; + IFCFile file = exporterIFC.GetFile(); + + IList xxp = new List(); + xxp.Add(1.0); xxp.Add(0.0); + xDirPos2D = IFCInstanceExporter.CreateDirection(file, xxp); + + IList xxn = new List(); + xxn.Add(-1.0); xxn.Add(0.0); + xDirNeg2D = IFCInstanceExporter.CreateDirection(file, xxn); + + IList yyp = new List(); + yyp.Add(0.0); yyp.Add(1.0); + yDirPos2D = IFCInstanceExporter.CreateDirection(file, yyp); - return siUnit; + IList yyn = new List(); + yyn.Add(0.0); yyn.Add(-1.0); + yDirNeg2D = IFCInstanceExporter.CreateDirection(file, yyn); + ExporterIFCUtils.SetGlobal2DDirectionHandles(true, xDirPos2D, yDirPos2D); + ExporterIFCUtils.SetGlobal2DDirectionHandles(false, xDirNeg2D, yDirNeg2D); } /// - /// Creates the IfcUnitAssignment. This is a long list of units that we correctly translate from our internal units to known units. + /// Creates the global cartesian origin then sets the 3D and 2D origins. /// /// The IFC exporter object. - /// The document provides ProjectUnit and DisplayUnitSystem. - /// The IFC handle. - private IFCAnyHandle CreateDefaultUnits(ExporterIFC exporterIFC, Document doc) + private void CreateGlobalCartesianOrigin(ExporterIFC exporterIFC) { - HashSet unitSet = new HashSet(); + + IFCAnyHandle origin2d = null; + IFCAnyHandle origin = null; + IFCFile file = exporterIFC.GetFile(); - bool exportToCOBIE = ExporterCacheManager.ExportOptionsCache.ExportAsCOBIE; + IList measure = new List(); + measure.Add(0.0); measure.Add(0.0); measure.Add(0.0); + origin = IFCInstanceExporter.CreateCartesianPoint(file, measure); + + IList measure2d = new List(); + measure2d.Add(0.0); measure2d.Add(0.0); + origin2d = IFCInstanceExporter.CreateCartesianPoint(file, measure2d); + ExporterIFCUtils.SetGlobal3DOriginHandle(origin); + ExporterIFCUtils.SetGlobal2DOriginHandle(origin2d); + } + + private static bool ValidateContainedHandle(IFCAnyHandle initialHandle) + { + if (ExporterCacheManager.ElementsInAssembliesCache.Contains(initialHandle)) + return false; - Dictionary, IFCAnyHandle> addedDerivedUnitElements = new Dictionary, IFCAnyHandle>(); - Action, IFCAnyHandle, int> createDerivedUnitElement = (elements, unit, exponent) => + try { - var pair = new Tuple(unit, exponent); - if (!addedDerivedUnitElements.ContainsKey(pair)) - { - var element = IFCInstanceExporter.CreateDerivedUnitElement(file, unit, exponent); - elements.Add(addedDerivedUnitElements[pair] = element); - } + if (!IFCAnyHandleUtil.HasRelDecomposes(initialHandle)) + return true; + } + catch + { + } + + return false; + } - elements.Add(addedDerivedUnitElements[pair]); - }; + /// + /// Remove contained or invalid handles from this set. + /// + /// The initial set that may have contained or invalid handles. + /// A cleaned set. + public static HashSet RemoveContainedHandlesFromSet(ICollection initialSet) + { + HashSet filteredSet = new HashSet(); - IFCAnyHandle lenSIBaseUnit = null; + if (initialSet != null) { - bool lenConversionBased = false; - bool lenUseDefault = false; - - IFCUnit lenUnitType = IFCUnit.LengthUnit; - IFCSIPrefix? lenPrefix = null; - IFCSIUnitName lenUnitName = IFCSIUnitName.Metre; - string lenConvName = null; - - FormatOptions lenFormatOptions = doc.GetUnits().GetFormatOptions(SpecTypeId.Length); - ForgeTypeId lengthUnit = lenFormatOptions.GetUnitTypeId(); - if (lengthUnit.Equals(UnitTypeId.Meters) || - lengthUnit.Equals(UnitTypeId.MetersCentimeters)) - { - // This space intentionally left blank - } - else if (lengthUnit.Equals(UnitTypeId.Centimeters)) - { - lenPrefix = IFCSIPrefix.Centi; - } - else if (lengthUnit.Equals(UnitTypeId.Millimeters)) - { - lenPrefix = IFCSIPrefix.Milli; - } - else if (lengthUnit.Equals(UnitTypeId.Feet) || - lengthUnit.Equals(UnitTypeId.FeetFractionalInches)) - { - if (exportToCOBIE) - lenConvName = "foot"; - else - lenConvName = "FOOT"; - lenConversionBased = true; - } - else if (lengthUnit.Equals(UnitTypeId.FractionalInches) || - lengthUnit.Equals(UnitTypeId.Inches)) - { - if (exportToCOBIE) - lenConvName = "inch"; - else - lenConvName = "INCH"; - lenConversionBased = true; - } - else + foreach (IFCAnyHandle initialHandle in initialSet) { - //Couldn't find display unit type conversion -- assuming foot - if (exportToCOBIE) - lenConvName = "foot"; - else - lenConvName = "FOOT"; - lenConversionBased = true; - lenUseDefault = true; + if (ValidateContainedHandle(initialHandle)) + filteredSet.Add(initialHandle); } + } - double lengthScaleFactor = UnitUtils.ConvertFromInternalUnits(1.0, lenUseDefault ? UnitTypeId.Feet : lenFormatOptions.GetUnitTypeId()); - IFCAnyHandle lenSIUnit = IFCInstanceExporter.CreateSIUnit(file, lenUnitType, lenPrefix, lenUnitName); - if (lenPrefix == null) - lenSIBaseUnit = lenSIUnit; - else - lenSIBaseUnit = IFCInstanceExporter.CreateSIUnit(file, lenUnitType, null, lenUnitName); + return filteredSet; + } - if (lenConversionBased) - { - double lengthSIScaleFactor = UnitUtils.ConvertFromInternalUnits(1.0, UnitTypeId.Meters) / lengthScaleFactor; - IFCAnyHandle lenDims = IFCInstanceExporter.CreateDimensionalExponents(file, 1, 0, 0, 0, 0, 0, 0); // length - IFCAnyHandle lenConvFactor = IFCInstanceExporter.CreateMeasureWithUnit(file, Toolkit.IFCDataUtil.CreateAsLengthMeasure(lengthSIScaleFactor), - lenSIUnit); - lenSIUnit = IFCInstanceExporter.CreateConversionBasedUnit(file, lenDims, lenUnitType, lenConvName, lenConvFactor); - } + private class IFCLevelExportInfo + { + public IFCLevelExportInfo() { } - unitSet.Add(lenSIUnit); // created above, so unique. - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.Length, lenSIUnit, lengthScaleFactor, 0.0); - } + public IDictionary> LevelMapping { get; set; } = + new Dictionary>(); - { - bool areaConversionBased = false; - bool areaUseDefault = false; + public IList OrphanedLevelInfos { get; set; } = new List(); - IFCUnit areaUnitType = IFCUnit.AreaUnit; - IFCSIPrefix? areaPrefix = null; - IFCSIUnitName areaUnitName = IFCSIUnitName.Square_Metre; - string areaConvName = null; + public void UnionLevelInfoRelated(ElementId toLevelId, IFCLevelInfo fromLevel) + { + if (fromLevel == null) + return; - FormatOptions areaFormatOptions = doc.GetUnits().GetFormatOptions(SpecTypeId.Area); - ForgeTypeId areaUnit = areaFormatOptions.GetUnitTypeId(); - if (areaUnit.Equals(UnitTypeId.SquareMeters)) - { - // This space intentionally left blank. - } - else if (areaUnit.Equals(UnitTypeId.SquareCentimeters)) - { - areaPrefix = IFCSIPrefix.Centi; - } - else if (areaUnit.Equals(UnitTypeId.SquareMillimeters)) - { - areaPrefix = IFCSIPrefix.Milli; - } - else if (areaUnit.Equals(UnitTypeId.SquareFeet)) - { - if (exportToCOBIE) - areaConvName = "foot"; - else - areaConvName = "SQUARE FOOT"; - areaConversionBased = true; - } - else if (areaUnit.Equals(UnitTypeId.SquareInches)) - { - if (exportToCOBIE) - areaConvName = "inch"; - else - areaConvName = "SQUARE INCH"; - areaConversionBased = true; - } - else + if (toLevelId == ElementId.InvalidElementId) { - //Couldn't find display unit type conversion -- assuming foot - if (exportToCOBIE) - areaConvName = "foot"; - else - areaConvName = "SQUARE FOOT"; - areaConversionBased = true; - areaUseDefault = true; + OrphanedLevelInfos.Add(fromLevel); + return; } - double areaScaleFactor = UnitUtils.ConvertFromInternalUnits(1.0, areaUseDefault ? UnitTypeId.SquareFeet : areaFormatOptions.GetUnitTypeId()); - IFCAnyHandle areaSiUnit = IFCInstanceExporter.CreateSIUnit(file, areaUnitType, areaPrefix, areaUnitName); - if (areaConversionBased) + IList levelMappingList; + if (!LevelMapping.TryGetValue(toLevelId, out levelMappingList)) { - double areaSIScaleFactor = areaScaleFactor * UnitUtils.ConvertFromInternalUnits(1.0, UnitTypeId.SquareMeters); - IFCAnyHandle areaDims = IFCInstanceExporter.CreateDimensionalExponents(file, 2, 0, 0, 0, 0, 0, 0); // area - IFCAnyHandle areaConvFactor = IFCInstanceExporter.CreateMeasureWithUnit(file, Toolkit.IFCDataUtil.CreateAsAreaMeasure(areaSIScaleFactor), areaSiUnit); - areaSiUnit = IFCInstanceExporter.CreateConversionBasedUnit(file, areaDims, areaUnitType, areaConvName, areaConvFactor); + levelMappingList = new List(); + LevelMapping[toLevelId] = levelMappingList; } - - unitSet.Add(areaSiUnit); // created above, so unique. - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.Area, areaSiUnit, areaScaleFactor, 0.0); + levelMappingList.Add(fromLevel); } + public void TransferOrphanedLevelInfo(ElementId toLevelId) { - bool volumeConversionBased = false; - bool volumeUseDefault = false; - - IFCUnit volumeUnitType = IFCUnit.VolumeUnit; - IFCSIPrefix? volumePrefix = null; - IFCSIUnitName volumeUnitName = IFCSIUnitName.Cubic_Metre; - string volumeConvName = null; - - FormatOptions volumeFormatOptions = doc.GetUnits().GetFormatOptions(SpecTypeId.Volume); - ForgeTypeId volumeUnit = volumeFormatOptions.GetUnitTypeId(); - if (volumeUnit.Equals(UnitTypeId.CubicMeters)) - { - // This space intentionally left blank. - } - else if (volumeUnit.Equals(UnitTypeId.Liters)) - { - volumePrefix = IFCSIPrefix.Deci; - } - else if (volumeUnit.Equals(UnitTypeId.CubicCentimeters)) - { - volumePrefix = IFCSIPrefix.Centi; - } - else if (volumeUnit.Equals(UnitTypeId.CubicMillimeters)) - { - volumePrefix = IFCSIPrefix.Milli; - } - else if (volumeUnit.Equals(UnitTypeId.CubicFeet)) - { - if (exportToCOBIE) - volumeConvName = "foot"; - else - volumeConvName = "CUBIC FOOT"; - volumeConversionBased = true; - } - else if (volumeUnit.Equals(UnitTypeId.CubicInches)) - { - if (exportToCOBIE) - volumeConvName = "inch"; - else - volumeConvName = "CUBIC INCH"; - volumeConversionBased = true; - } - else - { - //Couldn't find display unit type conversion -- assuming foot - if (exportToCOBIE) - volumeConvName = "foot"; - else - volumeConvName = "CUBIC FOOT"; - volumeConversionBased = true; - volumeUseDefault = true; - } - - double volumeScaleFactor = - UnitUtils.ConvertFromInternalUnits(1.0, volumeUseDefault ? UnitTypeId.CubicFeet : volumeFormatOptions.GetUnitTypeId()); - IFCAnyHandle volumeSiUnit = IFCInstanceExporter.CreateSIUnit(file, volumeUnitType, volumePrefix, volumeUnitName); - if (volumeConversionBased) - { - double volumeSIScaleFactor = volumeScaleFactor * UnitUtils.ConvertFromInternalUnits(1.0, UnitTypeId.CubicMeters); - IFCAnyHandle volumeDims = IFCInstanceExporter.CreateDimensionalExponents(file, 3, 0, 0, 0, 0, 0, 0); // volume - IFCAnyHandle volumeConvFactor = IFCInstanceExporter.CreateMeasureWithUnit(file, Toolkit.IFCDataUtil.CreateAsVolumeMeasure(volumeSIScaleFactor), volumeSiUnit); - volumeSiUnit = IFCInstanceExporter.CreateConversionBasedUnit(file, volumeDims, volumeUnitType, volumeConvName, volumeConvFactor); - } - - unitSet.Add(volumeSiUnit); // created above, so unique. - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.Volume, volumeSiUnit, volumeScaleFactor, 0.0); - } - - IFCAnyHandle angleSIUnit = null; - { - IFCUnit unitType = IFCUnit.PlaneAngleUnit; - IFCSIUnitName unitName = IFCSIUnitName.Radian; - - angleSIUnit = IFCInstanceExporter.CreateSIUnit(file, unitType, null, unitName); - - string convName = null; - - FormatOptions angleFormatOptions = doc.GetUnits().GetFormatOptions(SpecTypeId.Angle); - bool angleUseDefault = false; - ForgeTypeId angleUnit = angleFormatOptions.GetUnitTypeId(); - if (angleUnit.Equals(UnitTypeId.Degrees) || - angleUnit.Equals(UnitTypeId.DegreesMinutes)) - { - convName = "DEGREE"; - } - else if (angleUnit.Equals(UnitTypeId.Gradians)) - { - convName = "GRAD"; - } - else if (angleUnit.Equals(UnitTypeId.Radians)) - { - // This space intentionally left blank. - } - else - { - angleUseDefault = true; - convName = "DEGREE"; - } - - IFCAnyHandle dims = IFCInstanceExporter.CreateDimensionalExponents(file, 0, 0, 0, 0, 0, 0, 0); - - IFCAnyHandle planeAngleUnit = angleSIUnit; - double angleScaleFactor = UnitUtils.Convert(1.0, angleUseDefault ? UnitTypeId.Degrees : angleFormatOptions.GetUnitTypeId(), UnitTypeId.Radians); - if (convName != null) - { - IFCAnyHandle convFactor = IFCInstanceExporter.CreateMeasureWithUnit(file, Toolkit.IFCDataUtil.CreateAsPlaneAngleMeasure(angleScaleFactor), planeAngleUnit); - planeAngleUnit = IFCInstanceExporter.CreateConversionBasedUnit(file, dims, unitType, convName, convFactor); - } - unitSet.Add(planeAngleUnit); // created above, so unique. - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.Angle, planeAngleUnit, 1.0 / angleScaleFactor, 0.0); - } - - // Mass - IFCAnyHandle massSIUnit = null; - { - massSIUnit = CreateSIUnit(file, SpecTypeId.Mass, IFCUnit.MassUnit, IFCSIUnitName.Gram, IFCSIPrefix.Kilo, null); - // If we are exporting to GSA standard, we will override kg with pound below. - if (!exportToCOBIE) - unitSet.Add(massSIUnit); // created above, so unique. - } - - // Mass density - support metric kg/(m^3) only. - { - ISet elements = new HashSet(); - createDerivedUnitElement(elements, massSIUnit, 1); - createDerivedUnitElement(elements, lenSIBaseUnit, -3); - - IFCAnyHandle massDensityUnit = IFCInstanceExporter.CreateDerivedUnit(file, elements, - IFCDerivedUnitEnum.MassDensityUnit, null); - unitSet.Add(massDensityUnit); - - double massDensityFactor = UnitUtils.ConvertFromInternalUnits(1.0, UnitTypeId.KilogramsPerCubicMeter); - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.MassDensity, massDensityUnit, massDensityFactor, 0.0); - } - - // Ion concentration - support metric kg/(m^3) only. - { - ISet elements = new HashSet(); - createDerivedUnitElement(elements, massSIUnit, 1); - createDerivedUnitElement(elements, lenSIBaseUnit, -3); - - IFCAnyHandle massDensityUnit = IFCInstanceExporter.CreateDerivedUnit(file, elements, - IFCDerivedUnitEnum.IonConcentrationUnit, null); - unitSet.Add(massDensityUnit); - - double massDensityFactor = UnitUtils.ConvertFromInternalUnits(1.0, UnitTypeId.KilogramsPerCubicMeter); - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.PipingDensity, massDensityUnit, massDensityFactor, 0.0); - } - - // Moment of inertia - support metric m^4. - { - ISet elements = new HashSet(); - createDerivedUnitElement(elements, lenSIBaseUnit, 4); - - IFCAnyHandle momentOfInertiaUnit = IFCInstanceExporter.CreateDerivedUnit(file, elements, - IFCDerivedUnitEnum.MomentOfInertiaUnit, null); - unitSet.Add(momentOfInertiaUnit); - - double momentOfInertiaFactor = UnitUtils.ConvertFromInternalUnits(1.0, UnitTypeId.MetersToTheFourthPower); - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.MomentOfInertia, momentOfInertiaUnit, momentOfInertiaFactor, 0.0); - } - - // Time -- support seconds only. - IFCAnyHandle timeSIUnit = null; - { - timeSIUnit = CreateSIUnit(file, null, IFCUnit.TimeUnit, IFCSIUnitName.Second, null, null); - unitSet.Add(timeSIUnit); // created above, so unique. - } - - // Frequency = support Hertz only. - { - IFCAnyHandle frequencySIUnit = CreateSIUnit(file, null, IFCUnit.FrequencyUnit, IFCSIUnitName.Hertz, null, null); - unitSet.Add(frequencySIUnit); // created above, so unique. - } - - // Temperature - IFCAnyHandle tempBaseSIUnit = null; - { - // Base SI unit for temperature. - tempBaseSIUnit = CreateSIUnit(file, null, IFCUnit.ThermoDynamicTemperatureUnit, IFCSIUnitName.Kelvin, null, null); - - // We are going to have two entries: one for thermodynamic temperature (default), and one for color temperature. - FormatOptions tempFormatOptions = doc.GetUnits().GetFormatOptions(SpecTypeId.HvacTemperature); - IFCSIUnitName thermalTempUnit; - double offset = 0.0; - ForgeTypeId tempUnit = tempFormatOptions.GetUnitTypeId(); - if (tempUnit.Equals(UnitTypeId.Celsius) || - tempUnit.Equals(UnitTypeId.Fahrenheit)) - { - thermalTempUnit = IFCSIUnitName.Degree_Celsius; - offset = -273.15; - } - else - { - thermalTempUnit = IFCSIUnitName.Kelvin; - } - - IFCAnyHandle temperatureSIUnit = null; - if (thermalTempUnit != IFCSIUnitName.Kelvin) - temperatureSIUnit = IFCInstanceExporter.CreateSIUnit(file, IFCUnit.ThermoDynamicTemperatureUnit, null, thermalTempUnit); - else - temperatureSIUnit = tempBaseSIUnit; - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.HvacTemperature, temperatureSIUnit, 1.0, offset); - - unitSet.Add(temperatureSIUnit); // created above, so unique. - - // Color temperature. - // We don't add the color temperature to the unit set; it will be explicitly used. - IFCAnyHandle colorTempSIUnit = tempBaseSIUnit; - ExporterCacheManager.UnitsCache["COLORTEMPERATURE"] = colorTempSIUnit; - } - - // Thermal transmittance - support metric W/(m^2 * K) = kg/(K * s^3) only. - { - ISet elements = new HashSet(); - createDerivedUnitElement(elements, massSIUnit, 1); - createDerivedUnitElement(elements, tempBaseSIUnit, -1); - createDerivedUnitElement(elements, timeSIUnit, -3); - - IFCAnyHandle thermalTransmittanceUnit = IFCInstanceExporter.CreateDerivedUnit(file, elements, - IFCDerivedUnitEnum.ThermalTransmittanceUnit, null); - unitSet.Add(thermalTransmittanceUnit); - - double thermalTransmittanceFactor = UnitUtils.ConvertFromInternalUnits(1.0, UnitTypeId.WattsPerSquareMeterKelvin); - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.HeatTransferCoefficient, thermalTransmittanceUnit, thermalTransmittanceFactor, 0.0); - } - - // Thermal conductivity - support metric W/(m * K) = (kg * m)/(K * s^3) only. - { - ISet elements = new HashSet(); - createDerivedUnitElement(elements, massSIUnit, 1); - createDerivedUnitElement(elements, lenSIBaseUnit, 1); - createDerivedUnitElement(elements, tempBaseSIUnit, -1); - createDerivedUnitElement(elements, timeSIUnit, -3); - - IFCAnyHandle thermaConductivityUnit = IFCInstanceExporter.CreateDerivedUnit(file, elements, - IFCDerivedUnitEnum.ThermalConductanceUnit, null); - unitSet.Add(thermaConductivityUnit); - - double thermalConductivityFactor = UnitUtils.ConvertFromInternalUnits(1.0, UnitTypeId.WattsPerMeterKelvin); - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.ThermalConductivity, thermaConductivityUnit, thermalConductivityFactor, 0.0); - } - - // Volumetric Flow Rate - support metric L/s or m^3/s only. - { - IFCAnyHandle volumetricFlowRateLenUnit = null; - - FormatOptions flowFormatOptions = doc.GetUnits().GetFormatOptions(SpecTypeId.AirFlow); - ForgeTypeId forgeTypeId = flowFormatOptions.GetUnitTypeId(); - if (forgeTypeId.Equals(UnitTypeId.LitersPerSecond)) - { - volumetricFlowRateLenUnit = IFCInstanceExporter.CreateSIUnit(file, IFCUnit.LengthUnit, IFCSIPrefix.Deci, IFCSIUnitName.Metre); - } - else - { - volumetricFlowRateLenUnit = lenSIBaseUnit; // use m^3/s by default. - forgeTypeId = UnitTypeId.CubicMetersPerSecond; - } - double volumetricFlowRateFactor = UnitUtils.ConvertFromInternalUnits(1.0, forgeTypeId); - - ISet elements = new HashSet(); - createDerivedUnitElement(elements, volumetricFlowRateLenUnit, 3); - createDerivedUnitElement(elements, timeSIUnit, -1); - - IFCAnyHandle volumetricFlowRateUnit = IFCInstanceExporter.CreateDerivedUnit(file, elements, - IFCDerivedUnitEnum.VolumetricFlowRateUnit, null); - unitSet.Add(volumetricFlowRateUnit); - - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.AirFlow, volumetricFlowRateUnit, volumetricFlowRateFactor, 0.0); - } - - // Mass flow rate - support kg/s only. - { - ISet elements = new HashSet(); - createDerivedUnitElement(elements, massSIUnit, 1); - createDerivedUnitElement(elements, timeSIUnit, -1); - - IFCAnyHandle massFlowRateUnit = IFCInstanceExporter.CreateDerivedUnit(file, elements, - IFCDerivedUnitEnum.MassFlowRateUnit, null); - unitSet.Add(massFlowRateUnit); - - double massFlowRateFactor = UnitUtils.ConvertFromInternalUnits(1.0, UnitTypeId.KilogramsPerSecond); - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.PipingMassPerTime, massFlowRateUnit, massFlowRateFactor, 0.0); - } - - // Rotational frequency - support cycles/s only. - { - ISet elements = new HashSet(); - createDerivedUnitElement(elements, timeSIUnit, -1); - - IFCAnyHandle rotationalFrequencyUnit = IFCInstanceExporter.CreateDerivedUnit(file, elements, - IFCDerivedUnitEnum.RotationalFrequencyUnit, null); - unitSet.Add(rotationalFrequencyUnit); - - double rotationalFrequencyFactor = UnitUtils.ConvertFromInternalUnits(1.0, UnitTypeId.RevolutionsPerSecond); - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.AngularSpeed, rotationalFrequencyUnit, rotationalFrequencyFactor, 0.0); - } - - // Electrical current - support metric ampere only. - IFCAnyHandle currentSIUnit = null; - { - currentSIUnit = CreateSIUnit(file, SpecTypeId.Current, IFCUnit.ElectricCurrentUnit, IFCSIUnitName.Ampere, - null, UnitTypeId.Amperes); - unitSet.Add(currentSIUnit); // created above, so unique. - } - - // Electrical voltage - support metric volt only. - { - IFCAnyHandle voltageSIUnit = CreateSIUnit(file, SpecTypeId.ElectricalPotential, IFCUnit.ElectricVoltageUnit, IFCSIUnitName.Volt, - null, UnitTypeId.Volts); - unitSet.Add(voltageSIUnit); // created above, so unique. - } - - // Power - support metric watt only. - IFCAnyHandle powerSIUnit = null; - { - powerSIUnit = CreateSIUnit(file, SpecTypeId.HvacPower, IFCUnit.PowerUnit, IFCSIUnitName.Watt, - null, UnitTypeId.Watts); - unitSet.Add(powerSIUnit); // created above, so unique. - } - - // Force - support newtons (N), metric weight-force, us-weight-force and kips. - { - bool forceConversionBased = false; - bool forceUseDefault = false; - - IFCUnit forceUnitType = IFCUnit.ForceUnit; - IFCSIPrefix? forcePrefix = null; - IFCSIUnitName forceUnitName = IFCSIUnitName.Newton; - string forceConvName = null; - - FormatOptions forceFormatOptions = doc.GetUnits().GetFormatOptions(SpecTypeId.Force); - ForgeTypeId forceUnit = forceFormatOptions.GetUnitTypeId(); - if (forceUnit.Equals(UnitTypeId.Newtons)) - { - // This space intentionally left blank. - } - else if (forceUnit.Equals(UnitTypeId.Dekanewtons)) - { - forcePrefix = IFCSIPrefix.Deca; - } - else if (forceUnit.Equals(UnitTypeId.Kilonewtons)) - { - forcePrefix = IFCSIPrefix.Kilo; - } - else if (forceUnit.Equals(UnitTypeId.Meganewtons)) - { - forcePrefix = IFCSIPrefix.Mega; - } - else if (forceUnit.Equals(UnitTypeId.KilogramsForce)) - { - forceConvName = "KILOGRAM-FORCE"; - } - else if (forceUnit.Equals(UnitTypeId.TonnesForce)) - { - forceConvName = "TONN-FORCE"; - } - else if (forceUnit.Equals(UnitTypeId.UsTonnesForce)) - { - forceConvName = "USTONN-FORCE"; - forceConversionBased = true; - } - else if (forceUnit.Equals(UnitTypeId.PoundsForce)) - { - forceConvName = "POUND-FORCE"; - forceConversionBased = true; - } - else if (forceUnit.Equals(UnitTypeId.Kips)) - { - forceConvName = "KIP"; - forceConversionBased = true; - } - else - { - //Couldn't find display unit type conversion -- assuming newton - forceUnit = UnitTypeId.Newtons; - forceUseDefault = true; - } - - if (exportToCOBIE && forceConvName != null) - forceConvName = forceConvName.ToLower(); - - double forceScaleFactor = UnitUtils.ConvertFromInternalUnits(1.0, forceUseDefault ? UnitTypeId.Newtons : forceFormatOptions.GetUnitTypeId()); - IFCAnyHandle forceSiUnit = IFCInstanceExporter.CreateSIUnit(file, forceUnitType, forcePrefix, forceUnitName); - if (forceConversionBased) - { - double forceSIScaleFactor = forceScaleFactor * UnitUtils.ConvertFromInternalUnits(1.0, UnitTypeId.Newtons); - IFCAnyHandle forceDims = IFCInstanceExporter.CreateDimensionalExponents(file, 1, 1, -2, 0, 0, 0, 0); // force - IFCAnyHandle forceConvFactor = IFCInstanceExporter.CreateMeasureWithUnit(file, Toolkit.IFCDataUtil.CreateAsForceMeasure(forceSIScaleFactor), forceSiUnit); - forceSiUnit = IFCInstanceExporter.CreateConversionBasedUnit(file, forceDims, forceUnitType, forceConvName, forceConvFactor); - } - - unitSet.Add(forceSiUnit); // created above, so unique. - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.Force, forceSiUnit, forceScaleFactor, 0.0); - } - - // Illuminance - { - IFCSIPrefix? prefix = null; - IFCAnyHandle luxSIUnit = CreateSIUnit(file, SpecTypeId.Illuminance, IFCUnit.IlluminanceUnit, IFCSIUnitName.Lux, - prefix, UnitTypeId.Lux); - unitSet.Add(luxSIUnit); // created above, so unique. - ExporterCacheManager.UnitsCache["LUX"] = luxSIUnit; - } - - // Luminous Flux - IFCAnyHandle lumenSIUnit = null; - { - IFCSIPrefix? prefix = null; - lumenSIUnit = CreateSIUnit(file, SpecTypeId.LuminousFlux, IFCUnit.LuminousFluxUnit, IFCSIUnitName.Lumen, - prefix, UnitTypeId.Lumens); - unitSet.Add(lumenSIUnit); // created above, so unique. - } - - // Luminous Intensity - { - IFCSIPrefix? prefix = null; - IFCAnyHandle candelaSIUnit = CreateSIUnit(file, SpecTypeId.LuminousIntensity, IFCUnit.LuminousIntensityUnit, IFCSIUnitName.Candela, - prefix, UnitTypeId.Candelas); - unitSet.Add(candelaSIUnit); // created above, so unique. - } - - // Energy - { - IFCSIPrefix? prefix = null; - IFCAnyHandle jouleSIUnit = CreateSIUnit(file, SpecTypeId.Energy, IFCUnit.EnergyUnit, IFCSIUnitName.Joule, - prefix, UnitTypeId.Joules); - unitSet.Add(jouleSIUnit); // created above, so unique. - } - - // Luminous Efficacy - support lm/W only. - { - ISet elements = new HashSet(); - createDerivedUnitElement(elements, massSIUnit, -1); - createDerivedUnitElement(elements, lenSIBaseUnit, -2); - createDerivedUnitElement(elements, timeSIUnit, 3); - createDerivedUnitElement(elements, lumenSIUnit, 1); - - IFCAnyHandle luminousEfficacyUnit = IFCInstanceExporter.CreateDerivedUnit(file, elements, - IFCDerivedUnitEnum.UserDefined, "Luminous Efficacy"); - - double electricalEfficacyFactor = UnitUtils.ConvertFromInternalUnits(1.0, UnitTypeId.LumensPerWatt); - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.Efficacy, luminousEfficacyUnit, electricalEfficacyFactor, 0.0); - ExporterCacheManager.UnitsCache["LUMINOUSEFFICACY"] = luminousEfficacyUnit; - - unitSet.Add(luminousEfficacyUnit); - } - - // Electrical Resistivity - support Ohm * M = (kg * m^3)/(s^3 * A^2) only - { - ISet elements = new HashSet(); - createDerivedUnitElement(elements, massSIUnit, 1); - createDerivedUnitElement(elements, lenSIBaseUnit, 3); - createDerivedUnitElement(elements, timeSIUnit, -3); - createDerivedUnitElement(elements, currentSIUnit, -2); - - IFCAnyHandle electricalResistivityUnit = IFCInstanceExporter.CreateDerivedUnit(file, elements, - IFCDerivedUnitEnum.UserDefined, "Electrical Resistivity"); - - double electricalResistivityFactor = UnitUtils.ConvertFromInternalUnits(1.0, UnitTypeId.OhmMeters); - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.ElectricalResistivity, electricalResistivityUnit, electricalResistivityFactor, 0.0); - ExporterCacheManager.UnitsCache["ELECTRICALRESISTIVITY"] = electricalResistivityUnit; - - unitSet.Add(electricalResistivityUnit); - } - // Sound Power - support watt only. - { - ISet elements = new HashSet(); - createDerivedUnitElement(elements, massSIUnit, 1); - createDerivedUnitElement(elements, lenSIBaseUnit, 2); - createDerivedUnitElement(elements, timeSIUnit, -3); - - IFCAnyHandle soundPowerUnit = IFCInstanceExporter.CreateDerivedUnit(file, elements, - IFCDerivedUnitEnum.SoundPowerUnit, null); - unitSet.Add(soundPowerUnit); - - double soundPowerFactor = UnitUtils.ConvertFromInternalUnits(1.0, UnitTypeId.Watts); - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.Wattage, soundPowerUnit, soundPowerFactor, 0.0); - } - - // Sound Pressure - support Pascal only. - { - ISet elements = new HashSet(); - createDerivedUnitElement(elements, massSIUnit, 1); - createDerivedUnitElement(elements, lenSIBaseUnit, -1); - createDerivedUnitElement(elements, timeSIUnit, -2); - - IFCAnyHandle soundPressureUnit = IFCInstanceExporter.CreateDerivedUnit(file, elements, - IFCDerivedUnitEnum.SoundPressureUnit, null); - unitSet.Add(soundPressureUnit); - - double soundPressureFactor = UnitUtils.ConvertFromInternalUnits(1.0, UnitTypeId.Pascals); - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.HvacPressure, soundPressureUnit, soundPressureFactor, 0.0); - } - - // Linear Velocity - support m/s only. - { - ISet elements = new HashSet(); - createDerivedUnitElement(elements, lenSIBaseUnit, 1); - createDerivedUnitElement(elements, timeSIUnit, -1); - - IFCAnyHandle linearVelocityUnit = IFCInstanceExporter.CreateDerivedUnit(file, elements, - IFCDerivedUnitEnum.LinearVelocityUnit, null); - - double linearVelocityFactor = UnitUtils.ConvertFromInternalUnits(1.0, UnitTypeId.MetersPerSecond); - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.HvacVelocity, linearVelocityUnit, linearVelocityFactor, 0.0); - - unitSet.Add(linearVelocityUnit); - } - - // Currency - disallowed for IC2x3 Coordination View 2.0. If we find a currency, export it as a real. - if (!ExporterCacheManager.ExportOptionsCache.ExportAs2x3CoordinationView2) - { - FormatOptions currencyFormatOptions = doc.GetUnits().GetFormatOptions(SpecTypeId.Currency); - ForgeTypeId currencySymbol = currencyFormatOptions.GetSymbolTypeId(); - - IFCAnyHandle currencyUnit = null; - - // Some of these are guesses for IFC2x3, since multiple currencies may use the same symbol, - // but no detail is given on which currency is being used. For IFC4, we just use the label. - if (!ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4) - { - string currencyLabel = null; - try - { - currencyLabel = LabelUtils.GetLabelForSymbol(currencySymbol); - currencyUnit = IFCInstanceExporter.CreateMonetaryUnit4(file, currencyLabel); - } - catch - { - currencyUnit = null; - } - } - else - { - IFCCurrencyType? currencyType = null; - - if (currencySymbol.Equals(SymbolTypeId.UsDollar)) - { - currencyType = IFCCurrencyType.USD; - } - else if (currencySymbol.Equals(SymbolTypeId.EuroPrefix) || - currencySymbol.Equals(SymbolTypeId.EuroSuffix)) - { - currencyType = IFCCurrencyType.EUR; - } - else if (currencySymbol.Equals(SymbolTypeId.UkPound)) - { - currencyType = IFCCurrencyType.GBP; - } - else if (currencySymbol.Equals(SymbolTypeId.ChineseHongKongDollar)) - { - currencyType = IFCCurrencyType.HKD; - } - else if (currencySymbol.Equals(SymbolTypeId.Krone)) - { - currencyType = IFCCurrencyType.NOK; - } - else if (currencySymbol.Equals(SymbolTypeId.Shekel)) - { - currencyType = IFCCurrencyType.ILS; - } - else if (currencySymbol.Equals(SymbolTypeId.Yen)) - { - currencyType = IFCCurrencyType.JPY; - } - else if (currencySymbol.Equals(SymbolTypeId.Won)) - { - currencyType = IFCCurrencyType.KRW; - } - else if (currencySymbol.Equals(SymbolTypeId.Baht)) - { - currencyType = IFCCurrencyType.THB; - } - else if (currencySymbol.Equals(SymbolTypeId.Dong)) - { - currencyType = IFCCurrencyType.VND; - } - - if (currencyType.HasValue) - currencyUnit = IFCInstanceExporter.CreateMonetaryUnit2x3(file, currencyType.Value); - } - - if (currencyUnit != null) - { - unitSet.Add(currencyUnit); // created above, so unique. - // We will cache the currency, if we create it. If we don't, we'll export currencies as numbers. - ExporterCacheManager.UnitsCache["CURRENCY"] = currencyUnit; - } - } - - // Pressure - support Pascal, kPa and MPa. - { - IFCSIPrefix? prefix = null; - FormatOptions pressureFormatOptions = doc.GetUnits().GetFormatOptions(SpecTypeId.HvacPressure); - ForgeTypeId pressureUnit = pressureFormatOptions.GetUnitTypeId(); - if (pressureUnit.Equals(UnitTypeId.Pascals)) - { - // This space intentionally left blank. - } - else if (pressureUnit.Equals(UnitTypeId.Kilopascals)) - { - prefix = IFCSIPrefix.Kilo; - } - else if (pressureUnit.Equals(UnitTypeId.Megapascals)) - { - prefix = IFCSIPrefix.Mega; - } - else - { - pressureUnit = UnitTypeId.Pascals; - } - - IFCAnyHandle pressureSIUnit = CreateSIUnit(file, SpecTypeId.HvacPressure, IFCUnit.PressureUnit, IFCSIUnitName.Pascal, - prefix, pressureUnit); - unitSet.Add(pressureSIUnit); // created above, so unique. - } - - // Friction loss - support Pa/m only. - { - ISet elements = new HashSet(); - createDerivedUnitElement(elements, lenSIBaseUnit, -2); - createDerivedUnitElement(elements, massSIUnit, 1); - createDerivedUnitElement(elements, timeSIUnit, -2); - - IFCAnyHandle frictionLossUnit = IFCInstanceExporter.CreateDerivedUnit(file, elements, - IFCDerivedUnitEnum.UserDefined, "Friction Loss"); - - double frictionLossFactor = UnitUtils.ConvertFromInternalUnits(1.0, UnitTypeId.PascalsPerMeter); - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.HvacFriction, frictionLossUnit, frictionLossFactor, 0.0); - ExporterCacheManager.UnitsCache["FRICTIONLOSS"] = frictionLossUnit; - - unitSet.Add(frictionLossUnit); - } - - // Area/Planar Force - support N/m2 only, and Linear Force - support N/m only - { - ISet elements = new HashSet(); - createDerivedUnitElement(elements, massSIUnit, 1); - createDerivedUnitElement(elements, timeSIUnit, -2); - - IFCAnyHandle linearForceUnit = IFCInstanceExporter.CreateDerivedUnit(file, elements, - IFCDerivedUnitEnum.LinearForceUnit, null); - - double linearForceFactor = UnitUtils.ConvertFromInternalUnits(1.0, UnitTypeId.NewtonsPerMeter); - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.LinearForce, linearForceUnit, linearForceFactor, 0.0); - unitSet.Add(linearForceUnit); - - elements = new HashSet(); - createDerivedUnitElement(elements, massSIUnit, 1); - createDerivedUnitElement(elements, lenSIBaseUnit, -1); - createDerivedUnitElement(elements, timeSIUnit, -2); - - IFCAnyHandle planarForceUnit = IFCInstanceExporter.CreateDerivedUnit(file, elements, - IFCDerivedUnitEnum.PlanarForceUnit, null); - - double planarForceFactor = UnitUtils.ConvertFromInternalUnits(1.0, UnitTypeId.NewtonsPerSquareMeter); - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.AreaForce, planarForceUnit, planarForceFactor, 0.0); - unitSet.Add(planarForceUnit); - } - - // Specific heat - support metric J/(kg * K) = m^2/(s^2 * K) only. - { - ISet elements = new HashSet(); - createDerivedUnitElement(elements, lenSIBaseUnit, 2); - createDerivedUnitElement(elements, timeSIUnit, -2); - createDerivedUnitElement(elements, tempBaseSIUnit, -1); - - IFCAnyHandle specificHeatUnit = IFCInstanceExporter.CreateDerivedUnit(file, elements, - IFCDerivedUnitEnum.SpecificHeatCapacityUnit, null); - unitSet.Add(specificHeatUnit); - - double specificHeatFactor = UnitUtils.ConvertFromInternalUnits(1.0, UnitTypeId.JoulesPerKilogramDegreeCelsius); - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.SpecificHeat, specificHeatUnit, specificHeatFactor, 0.0); - } - - // Heat flux density - support metric W/m^2 = kg/s^3 only. - { - ISet elements = new HashSet(); - createDerivedUnitElement(elements, massSIUnit, 1); - createDerivedUnitElement(elements, timeSIUnit, -3); - - IFCAnyHandle heatFluxDensityUnit = IFCInstanceExporter.CreateDerivedUnit(file, elements, - IFCDerivedUnitEnum.HeatFluxDensityUnit, null); - unitSet.Add(heatFluxDensityUnit); - - double heatFluxDensityFactor = UnitUtils.ConvertFromInternalUnits(1.0, UnitTypeId.WattsPerSquareMeter); - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.HvacPowerDensity, heatFluxDensityUnit, heatFluxDensityFactor, 0.0); - } - - // Heating value - support metric J/kg = m^2/s^2 only. - { - ISet elements = new HashSet(); - createDerivedUnitElement(elements, lenSIBaseUnit, 2); - createDerivedUnitElement(elements, timeSIUnit, -2); - - IFCAnyHandle heatingValueUnit = IFCInstanceExporter.CreateDerivedUnit(file, elements, - IFCDerivedUnitEnum.HeatingValueUnit, null); - unitSet.Add(heatingValueUnit); - - double heatingValueFactor = UnitUtils.ConvertFromInternalUnits(1.0, UnitTypeId.JoulesPerGram); - heatingValueFactor *= 1.0e+3; // --> gram to kilogram - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.SpecificHeatOfVaporization, heatingValueUnit, heatingValueFactor, 0.0); - } - - // Permeability (Permeance) - support metric kg/(Pa * s * m^2) = s/m only. - { - ISet elements = new HashSet(); - createDerivedUnitElement(elements, timeSIUnit, 1); - createDerivedUnitElement(elements, lenSIBaseUnit, -1); - - IFCAnyHandle permeabilityUnit = IFCInstanceExporter.CreateDerivedUnit(file, elements, - IFCDerivedUnitEnum.VaporPermeabilityUnit, null); - unitSet.Add(permeabilityUnit); - - double permeabilityFactor = UnitUtils.ConvertFromInternalUnits(1.0, UnitTypeId.NanogramsPerPascalSecondSquareMeter); - permeabilityFactor *= 1.0e-12; // --> Nanogram to kilogram - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.Permeability, permeabilityUnit, permeabilityFactor, 0.0); - } - - // Dynamic viscosity - support metric Pa * s = kg/(m * s) only. - { - ISet elements = new HashSet(); - createDerivedUnitElement(elements, massSIUnit, 1); - createDerivedUnitElement(elements, lenSIBaseUnit, -1); - createDerivedUnitElement(elements, timeSIUnit, -1); - - IFCAnyHandle viscosityUnit = IFCInstanceExporter.CreateDerivedUnit(file, elements, - IFCDerivedUnitEnum.DynamicViscosityUnit, null); - unitSet.Add(viscosityUnit); - - double viscosityFactor = UnitUtils.ConvertFromInternalUnits(1.0, UnitTypeId.KilogramsPerMeterSecond); - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.HvacViscosity, viscosityUnit, viscosityFactor, 0.0); - } - - // Thermal expansion coefficient - support metric 1/K only. - { - ISet elements = new HashSet(); - createDerivedUnitElement(elements, tempBaseSIUnit, -1); - - IFCAnyHandle thermalExpansionCoefficientUnit = IFCInstanceExporter.CreateDerivedUnit(file, elements, - IFCDerivedUnitEnum.ThermalExpansionCoefficientUnit, null); - unitSet.Add(thermalExpansionCoefficientUnit); - - double thermalExpansionCoefficientFactor = UnitUtils.ConvertFromInternalUnits(1.0, UnitTypeId.InverseDegreesCelsius); - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.ThermalExpansionCoefficient, thermalExpansionCoefficientUnit, thermalExpansionCoefficientFactor, 0.0); - } - - // Modulus of elasticity - support Pascal only. - { - ISet elements = new HashSet(); - createDerivedUnitElement(elements, massSIUnit, 1); - createDerivedUnitElement(elements, lenSIBaseUnit, -1); - createDerivedUnitElement(elements, timeSIUnit, -2); - - IFCAnyHandle modulusOfElasticityUnit = IFCInstanceExporter.CreateDerivedUnit(file, elements, - IFCDerivedUnitEnum.ModulusOfElasticityUnit, null); - unitSet.Add(modulusOfElasticityUnit); - - double modulusOfElasticityFactor = UnitUtils.ConvertFromInternalUnits(1.0, UnitTypeId.Pascals); - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.Stress, modulusOfElasticityUnit, modulusOfElasticityFactor, 0.0); - } - - // Isothermal moisture capacity - support m3 / kg only. - { - ISet elements = new HashSet(); - createDerivedUnitElement(elements, lenSIBaseUnit, 3); - createDerivedUnitElement(elements, massSIUnit, -1); - - IFCAnyHandle isothermalMoistureCapacityUnit = IFCInstanceExporter.CreateDerivedUnit(file, elements, - IFCDerivedUnitEnum.IsothermalMoistureCapacityUnit, null); - unitSet.Add(isothermalMoistureCapacityUnit); - - double isothermalMoistureCapacityFactor = UnitUtils.ConvertFromInternalUnits(1.0, UnitTypeId.CubicMetersPerKilogram); - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.IsothermalMoistureCapacity, isothermalMoistureCapacityUnit, isothermalMoistureCapacityFactor, 0.0); - } - - // Moisture diffusivity - support metric m^2/s only. - { - ISet elements = new HashSet(); - createDerivedUnitElement(elements, lenSIBaseUnit, 2); - createDerivedUnitElement(elements, timeSIUnit, -1); - - IFCAnyHandle moistureDiffusivityUnit = IFCInstanceExporter.CreateDerivedUnit(file, elements, - IFCDerivedUnitEnum.MoistureDiffusivityUnit, null); - unitSet.Add(moistureDiffusivityUnit); - - double moistureDiffusivityFactor = UnitUtils.ConvertFromInternalUnits(1.0, UnitTypeId.SquareMetersPerSecond); - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.Diffusivity, moistureDiffusivityUnit, moistureDiffusivityFactor, 0.0); - } - - // Area density - support metric kg/m^2 only. - if (!ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4) - { - ISet elements = new HashSet(); - createDerivedUnitElement(elements, massSIUnit, 1); - createDerivedUnitElement(elements, lenSIBaseUnit, 2); - - IFCAnyHandle areaDensityUnit = IFCInstanceExporter.CreateDerivedUnit(file, elements, - Toolkit.IFC4.IFCDerivedUnit.AREADENSITYUNIT, null); - unitSet.Add(areaDensityUnit); - - double areaDensityFactor = UnitUtils.ConvertFromInternalUnits(1.0, UnitTypeId.KilogramsPerSquareMeter); - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.MassPerUnitArea, areaDensityUnit, areaDensityFactor, 0.0); - } - - // Mass per length - support metric kg/m only. - { - ISet elements = new HashSet(); - createDerivedUnitElement(elements, massSIUnit, 1); - createDerivedUnitElement(elements, lenSIBaseUnit, -1); - - IFCAnyHandle massPerLenghtUnit = IFCInstanceExporter.CreateDerivedUnit(file, elements, - IFCDerivedUnitEnum.MassPerLengthUnit, null); - unitSet.Add(massPerLenghtUnit); - - double massPerLenghtFactor = UnitUtils.ConvertFromInternalUnits(1.0, UnitTypeId.KilogramsPerMeter); - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.MassPerUnitLength, massPerLenghtUnit, massPerLenghtFactor, 0.0); - } - - // Thermal resistance - support metric (m^2 * K)/W = (s^3 * K) / kg only. - { - ISet elements = new HashSet(); - createDerivedUnitElement(elements, timeSIUnit, 3); - createDerivedUnitElement(elements, tempBaseSIUnit, 1); - createDerivedUnitElement(elements, massSIUnit, -1); - - IFCAnyHandle thermalResistanceUnit = IFCInstanceExporter.CreateDerivedUnit(file, elements, - IFCDerivedUnitEnum.ThermalResistanceUnit, null); - unitSet.Add(thermalResistanceUnit); - - double thermalResistanceFactor = UnitUtils.ConvertFromInternalUnits(1.0, UnitTypeId.SquareMeterKelvinsPerWatt); - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.ThermalResistance, thermalResistanceUnit, thermalResistanceFactor, 0.0); - } - - // Acceleration - support metric m/s^2 only. - { - ISet elements = new HashSet(); - createDerivedUnitElement(elements, lenSIBaseUnit, 1); - createDerivedUnitElement(elements, timeSIUnit, -2); - - IFCAnyHandle thermalResistanceUnit = IFCInstanceExporter.CreateDerivedUnit(file, elements, - IFCDerivedUnitEnum.AccelerationUnit, null); - unitSet.Add(thermalResistanceUnit); - - double thermalResistanceFactor = UnitUtils.ConvertFromInternalUnits(1.0, UnitTypeId.MetersPerSecondSquared); - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.Acceleration, thermalResistanceUnit, thermalResistanceFactor, 0.0); - } - - // Angular velocity - support rad/s only. - { - ISet elements = new HashSet(); - - createDerivedUnitElement(elements, angleSIUnit, 1); - createDerivedUnitElement(elements, timeSIUnit, -1); - - IFCAnyHandle angularVelocityUnit = IFCInstanceExporter.CreateDerivedUnit(file, elements, - IFCDerivedUnitEnum.AngularVelocityUnit, null); - unitSet.Add(angularVelocityUnit); - - double angularVelocityFactor = UnitUtils.ConvertFromInternalUnits(1.0, UnitTypeId.RadiansPerSecond); - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.Pulsation, angularVelocityUnit, angularVelocityFactor, 0.0); - } - - // Linear stiffness - support N/m = kg/s^2 only. - { - ISet elements = new HashSet(); - - createDerivedUnitElement(elements, massSIUnit, 1); - createDerivedUnitElement(elements, timeSIUnit, -2); - - IFCAnyHandle linearStiffnessUnit = IFCInstanceExporter.CreateDerivedUnit(file, elements, - IFCDerivedUnitEnum.LinearStiffnessUnit, null); - unitSet.Add(linearStiffnessUnit); - - double linearStiffnessFactor = UnitUtils.ConvertFromInternalUnits(1.0, UnitTypeId.NewtonsPerMeter); - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.PointSpringCoefficient, linearStiffnessUnit, linearStiffnessFactor, 0.0); - } - - // Warping constant - support m^6 only. - { - ISet elements = new HashSet(); - - createDerivedUnitElement(elements, lenSIBaseUnit, 6); - - IFCAnyHandle wrappingConstantUnit = IFCInstanceExporter.CreateDerivedUnit(file, elements, - IFCDerivedUnitEnum.WarpingConstantUnit, null); - unitSet.Add(wrappingConstantUnit); - - double wrappingConstantFactor = UnitUtils.ConvertFromInternalUnits(1.0, UnitTypeId.MetersToTheSixthPower); - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.WarpingConstant, wrappingConstantUnit, wrappingConstantFactor, 0.0); - } - - // Linear moment - support N-m / m = (kg * m)/s^2 only. - { - ISet elements = new HashSet(); - - createDerivedUnitElement(elements, massSIUnit, 1); - createDerivedUnitElement(elements, lenSIBaseUnit, 1); - createDerivedUnitElement(elements, timeSIUnit, -2); - - IFCAnyHandle linearMomentUnit = IFCInstanceExporter.CreateDerivedUnit(file, elements, - IFCDerivedUnitEnum.LinearMomentUnit, null); - unitSet.Add(linearMomentUnit); - - double linearMomentFactor = UnitUtils.ConvertFromInternalUnits(1.0, UnitTypeId.NewtonMetersPerMeter); - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.LinearMoment, linearMomentUnit, linearMomentFactor, 0.0); - } - - // Torque - support N-m = (kg * m^2)/s^2 only. - { - ISet elements = new HashSet(); - - createDerivedUnitElement(elements, massSIUnit, 1); - createDerivedUnitElement(elements, lenSIBaseUnit, 2); - createDerivedUnitElement(elements, timeSIUnit, -2); - - IFCAnyHandle torqueUnit = IFCInstanceExporter.CreateDerivedUnit(file, elements, - IFCDerivedUnitEnum.Torqueunit, null); - unitSet.Add(torqueUnit); - - double torqueFactor = UnitUtils.ConvertFromInternalUnits(1.0, UnitTypeId.NewtonMeters); - ExporterCacheManager.UnitsCache.AddUnit(SpecTypeId.Moment, torqueUnit, torqueFactor, 0.0); - } - - // GSA only units. - if (exportToCOBIE) - { - // Derived imperial mass unit - { - IFCUnit unitType = IFCUnit.MassUnit; - IFCAnyHandle dims = IFCInstanceExporter.CreateDimensionalExponents(file, 0, 1, 0, 0, 0, 0, 0); - double factor = 0.45359237; // --> pound to kilogram - string convName = "pound"; - - IFCAnyHandle convFactor = IFCInstanceExporter.CreateMeasureWithUnit(file, Toolkit.IFCDataUtil.CreateAsMassMeasure(factor), massSIUnit); - IFCAnyHandle massUnit = IFCInstanceExporter.CreateConversionBasedUnit(file, dims, unitType, convName, convFactor); - unitSet.Add(massUnit); // created above, so unique. - } - - // Air Changes per Hour - { - IFCUnit unitType = IFCUnit.FrequencyUnit; - IFCAnyHandle dims = IFCInstanceExporter.CreateDimensionalExponents(file, 0, 0, -1, 0, 0, 0, 0); - double factor = 1.0 / 3600.0; // --> seconds to hours - string convName = "ACH"; - - IFCAnyHandle convFactor = IFCInstanceExporter.CreateMeasureWithUnit(file, Toolkit.IFCDataUtil.CreateAsTimeMeasure(factor), timeSIUnit); - IFCAnyHandle achUnit = IFCInstanceExporter.CreateConversionBasedUnit(file, dims, unitType, convName, convFactor); - unitSet.Add(achUnit); // created above, so unique. - ExporterCacheManager.UnitsCache["ACH"] = achUnit; - } - } - - return IFCInstanceExporter.CreateUnitAssignment(file, unitSet); - } - - /// - /// Creates the global direction and sets the cardinal directions in 3D. - /// - /// The IFC exporter object. - private void CreateGlobalDirection(ExporterIFC exporterIFC) - { - // Note that we do not use the ExporterUtil.CreateDirection functions below, as they try - // to match the input XYZ to one of the "global" directions that we are creating below. - IFCAnyHandle xDirPos = null; - IFCAnyHandle xDirNeg = null; - IFCAnyHandle yDirPos = null; - IFCAnyHandle yDirNeg = null; - IFCAnyHandle zDirPos = null; - IFCAnyHandle zDirNeg = null; - - IFCFile file = exporterIFC.GetFile(); - IList xxp = new List(); - xxp.Add(1.0); xxp.Add(0.0); xxp.Add(0.0); - xDirPos = IFCInstanceExporter.CreateDirection(file, xxp); - - IList xxn = new List(); - xxn.Add(-1.0); xxn.Add(0.0); xxn.Add(0.0); - xDirNeg = IFCInstanceExporter.CreateDirection(file, xxn); - - IList yyp = new List(); - yyp.Add(0.0); yyp.Add(1.0); yyp.Add(0.0); - yDirPos = IFCInstanceExporter.CreateDirection(file, yyp); - - IList yyn = new List(); - yyn.Add(0.0); yyn.Add(-1.0); yyn.Add(0.0); - yDirNeg = IFCInstanceExporter.CreateDirection(file, yyn); - - IList zzp = new List(); - zzp.Add(0.0); zzp.Add(0.0); zzp.Add(1.0); - zDirPos = IFCInstanceExporter.CreateDirection(file, zzp); - - IList zzn = new List(); - zzn.Add(0.0); zzn.Add(0.0); zzn.Add(-1.0); - zDirNeg = IFCInstanceExporter.CreateDirection(file, zzn); - - ExporterIFCUtils.SetGlobal3DDirectionHandles(true, xDirPos, yDirPos, zDirPos); - ExporterIFCUtils.SetGlobal3DDirectionHandles(false, xDirNeg, yDirNeg, zDirNeg); - } - - /// - /// Creates the global direction and sets the cardinal directions in 2D. - /// - /// The IFC exporter object. - private void CreateGlobalDirection2D(ExporterIFC exporterIFC) - { - IFCAnyHandle xDirPos2D = null; - IFCAnyHandle xDirNeg2D = null; - IFCAnyHandle yDirPos2D = null; - IFCAnyHandle yDirNeg2D = null; - IFCFile file = exporterIFC.GetFile(); - - IList xxp = new List(); - xxp.Add(1.0); xxp.Add(0.0); - xDirPos2D = IFCInstanceExporter.CreateDirection(file, xxp); - - IList xxn = new List(); - xxn.Add(-1.0); xxn.Add(0.0); - xDirNeg2D = IFCInstanceExporter.CreateDirection(file, xxn); - - IList yyp = new List(); - yyp.Add(0.0); yyp.Add(1.0); - yDirPos2D = IFCInstanceExporter.CreateDirection(file, yyp); - - IList yyn = new List(); - yyn.Add(0.0); yyn.Add(-1.0); - yDirNeg2D = IFCInstanceExporter.CreateDirection(file, yyn); - ExporterIFCUtils.SetGlobal2DDirectionHandles(true, xDirPos2D, yDirPos2D); - ExporterIFCUtils.SetGlobal2DDirectionHandles(false, xDirNeg2D, yDirNeg2D); - } - - /// - /// Creates the global cartesian origin then sets the 3D and 2D origins. - /// - /// The IFC exporter object. - private void CreateGlobalCartesianOrigin(ExporterIFC exporterIFC) - { - - IFCAnyHandle origin2d = null; - IFCAnyHandle origin = null; - - IFCFile file = exporterIFC.GetFile(); - IList measure = new List(); - measure.Add(0.0); measure.Add(0.0); measure.Add(0.0); - origin = IFCInstanceExporter.CreateCartesianPoint(file, measure); - - IList measure2d = new List(); - measure2d.Add(0.0); measure2d.Add(0.0); - origin2d = IFCInstanceExporter.CreateCartesianPoint(file, measure2d); - ExporterIFCUtils.SetGlobal3DOriginHandle(origin); - ExporterIFCUtils.SetGlobal2DOriginHandle(origin2d); - } - - private static bool ValidateContainedHandle(IFCAnyHandle initialHandle) - { - if (ExporterCacheManager.ElementsInAssembliesCache.Contains(initialHandle)) - return false; - - try - { - if (!IFCAnyHandleUtil.HasRelDecomposes(initialHandle)) - return true; - } - catch - { - } - - return false; - } - - /// - /// Remove contained or invalid handles from this set. - /// - /// The initial set that may have contained or invalid handles. - /// A cleaned set. - public static HashSet RemoveContainedHandlesFromSet(ICollection initialSet) - { - HashSet filteredSet = new HashSet(); - - if (initialSet != null) - { - foreach (IFCAnyHandle initialHandle in initialSet) - { - if (ValidateContainedHandle(initialHandle)) - filteredSet.Add(initialHandle); - } - } - - return filteredSet; - } - - private class IFCLevelExportInfo - { - public IFCLevelExportInfo() { } - - public IDictionary> LevelMapping { get; set; } = - new Dictionary>(); - - public IList OrphanedLevelInfos { get; set; } = new List(); - - public void UnionLevelInfoRelated(ElementId toLevelId, IFCLevelInfo fromLevel) - { - if (fromLevel == null) - return; - - if (toLevelId == ElementId.InvalidElementId) - { - OrphanedLevelInfos.Add(fromLevel); - return; - } - - IList levelMappingList; - if (!LevelMapping.TryGetValue(toLevelId, out levelMappingList)) - { - levelMappingList = new List(); - LevelMapping[toLevelId] = levelMappingList; - } - levelMappingList.Add(fromLevel); - } - - public void TransferOrphanedLevelInfo(ElementId toLevelId) - { - if (toLevelId == ElementId.InvalidElementId) - return; + if (toLevelId == ElementId.InvalidElementId) + return; if (OrphanedLevelInfos.Count == 0) return; @@ -4672,48 +3612,86 @@ private IFCAnyHandle CreateBuildingPlacement(IFCFile file) return IFCInstanceExporter.CreateLocalPlacement(file, null, ExporterUtil.CreateAxis2Placement3D(file)); } - private IFCAnyHandle CreateBuildingFromProjectInfo(ExporterIFC exporterIFC, Document document, IFCAnyHandle buildingPlacement) + private IFCAnyHandle CreateFacilityFromProjectInfo(ExporterIFC exporterIFC, Document document, + IFCAnyHandle facilityPlacement, bool allowBuildingExport) { + KnownFacilityTypes facilityType = ExporterCacheManager.ExportOptionsCache.FacilityType; + bool exportingBuilding = facilityType == KnownFacilityTypes.Building; + if (exportingBuilding && !allowBuildingExport) + return null; + + COBieProjectInfo cobieProjectInfo = ExporterCacheManager.ExportOptionsCache.COBieProjectInfo; + bool exportingCOBIE = exportingBuilding && + ExporterCacheManager.ExportOptionsCache.ExportAs2x3COBIE24DesignDeliverable && + cobieProjectInfo != null; + ProjectInfo projectInfo = document.ProjectInformation; IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; - string buildingName = string.Empty; - string buildingDescription = null; - string buildingLongName = null; - string buildingObjectType = null; + string facilityName = string.Empty; + string facilityDescription = null; + string facilityLongName = null; + string facilityObjectType = null; - COBieProjectInfo cobieProjectInfo = ExporterCacheManager.ExportOptionsCache.COBieProjectInfo; - if (ExporterCacheManager.ExportOptionsCache.ExportAs2x3COBIE24DesignDeliverable && cobieProjectInfo != null) + if (exportingCOBIE) { - buildingName = cobieProjectInfo.BuildingName_Number; - buildingDescription = cobieProjectInfo.BuildingDescription; + facilityName = cobieProjectInfo.BuildingName_Number; + facilityDescription = cobieProjectInfo.BuildingDescription; } else if (projectInfo != null) { try { - buildingName = projectInfo.BuildingName; + facilityName = projectInfo.BuildingName; } catch (Autodesk.Revit.Exceptions.InvalidOperationException) { } - buildingDescription = NamingUtil.GetOverrideStringValue(projectInfo, "BuildingDescription", null); - buildingLongName = NamingUtil.GetOverrideStringValue(projectInfo, "BuildingLongName", buildingName); - buildingObjectType = NamingUtil.GetOverrideStringValue(projectInfo, "BuildingObjectType", null); + + facilityDescription = NamingUtil.GetOverrideStringValue(projectInfo, "FacilityDescription", null); + facilityLongName = NamingUtil.GetOverrideStringValue(projectInfo, "FacilityLongName", facilityName); + facilityObjectType = NamingUtil.GetOverrideStringValue(projectInfo, "FacilityObjectType", null); } IFCFile file = exporterIFC.GetFile(); - IFCAnyHandle address = null; - if (Exporter.NeedToCreateAddressForBuilding(document)) - address = Exporter.CreateIFCAddress(file, document, projectInfo); - - string buildingGUID = GUIDUtil.CreateProjectLevelGUID(document, GUIDUtil.ProjectLevelGUIDType.Building); - IFCAnyHandle buildingHandle = IFCInstanceExporter.CreateBuilding(exporterIFC, - buildingGUID, ownerHistory, buildingName, buildingDescription, buildingObjectType, buildingPlacement, null, buildingLongName, - Toolkit.IFCElementComposition.Element, null, null, address); - ExporterCacheManager.BuildingHandle = buildingHandle; - - if (ExporterCacheManager.ExportOptionsCache.ExportAs2x3COBIE24DesignDeliverable && cobieProjectInfo != null) + IFCAnyHandle address = exportingBuilding && NeedToCreateAddressForBuilding(document) ? + CreateIFCAddress(file, document, projectInfo) : null; + + string facilityPredefinedType = ExporterCacheManager.ExportOptionsCache.FacilityPredefinedType; + + string facilityGUID = GUIDUtil.CreateProjectLevelGUID(document, GUIDUtil.ProjectLevelGUIDType.Building); + IFCAnyHandle facilityHandle = null; + + switch (facilityType) + { + case KnownFacilityTypes.Building: + facilityHandle = IFCInstanceExporter.CreateBuilding(exporterIFC, + facilityGUID, ownerHistory, facilityName, facilityDescription, facilityObjectType, facilityPlacement, null, + facilityLongName, IFCElementComposition.Element, null, null, address); + break; + case KnownFacilityTypes.Bridge: + facilityHandle =IFCInstanceExporter.CreateBridge(exporterIFC, + facilityGUID, ownerHistory, facilityName, facilityDescription, facilityObjectType, facilityPlacement, null, + facilityLongName, IFCElementComposition.Element, facilityPredefinedType); + break; + case KnownFacilityTypes.MarineFacility: + facilityHandle = IFCInstanceExporter.CreateMarineFacility(exporterIFC, + facilityGUID, ownerHistory, facilityName, facilityDescription, facilityObjectType, facilityPlacement, null, + facilityLongName, IFCElementComposition.Element, facilityPredefinedType); + break; + case KnownFacilityTypes.Road: + facilityHandle = IFCInstanceExporter.CreateRoad(exporterIFC, + facilityGUID, ownerHistory, facilityName, facilityDescription, facilityObjectType, facilityPlacement, null, + facilityLongName, IFCElementComposition.Element, facilityPredefinedType); + break; + case KnownFacilityTypes.Railway: + facilityHandle = IFCInstanceExporter.CreateRailway(exporterIFC, + facilityGUID, ownerHistory, facilityName, facilityDescription, facilityObjectType, facilityPlacement, null, + facilityLongName, IFCElementComposition.Element, facilityPredefinedType); + break; + } + + if (exportingCOBIE) { string classificationParamValue = cobieProjectInfo.BuildingType; @@ -4723,16 +3701,17 @@ private IFCAnyHandle CreateBuildingFromProjectInfo(ExporterIFC exporterIFC, Docu { string relGuidName = classificationItemCode + ":" + classificationItemName; string relGuid = GUIDUtil.GenerateIFCGuidFrom( - GUIDUtil.CreateGUIDString(IFCEntityType.IfcRelAssociatesClassification, relGuidName, - buildingHandle)); - ClassificationReferenceKey key = new ClassificationReferenceKey(null, + GUIDUtil.CreateGUIDString(IFCEntityType.IfcRelAssociatesClassification, relGuidName, + facilityHandle)); + ClassificationReferenceKey key = new ClassificationReferenceKey(null, classificationItemCode, classificationItemName, null, null); - ExporterCacheManager.ClassificationCache.AddRelation(file, key, relGuid, - "BuildingType", buildingHandle); + ExporterCacheManager.ClassificationCache.AddRelation(file, key, relGuid, + "BuildingType", facilityHandle); } } - return buildingHandle; + ExporterCacheManager.BuildingHandle = facilityHandle; + return facilityHandle; } /// @@ -4998,9 +3977,7 @@ private bool RememberWCSOrGeoReference (double eastings, double northings, doubl Element baseEquipment = systemElem.BaseEquipment; if (baseEquipment != null) { - IFCAnyHandle memberHandle = ExporterCacheManager.MEPCache.Find(baseEquipment.Id); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(memberHandle)) - system.Value.Add(memberHandle); + system.Value.AddIfNotNull(ExporterCacheManager.MEPCache.Find(baseEquipment.Id)); } if (isElectricalSystem) @@ -5012,9 +3989,7 @@ private bool RememberWCSOrGeoReference (double eastings, double northings, doubl ElementSet members = systemElem.Elements; foreach (Element member in members) { - IFCAnyHandle memberHandle = ExporterCacheManager.MEPCache.Find(member.Id); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(memberHandle)) - system.Value.Add(memberHandle); + system.Value.AddIfNotNull(ExporterCacheManager.MEPCache.Find(member.Id)); } } catch @@ -5028,8 +4003,7 @@ private bool RememberWCSOrGeoReference (double eastings, double northings, doubl ElementType systemElemType = doc.GetElement(systemElem.GetTypeId()) as ElementType; string name = NamingUtil.GetNameOverride(systemElem, systemElem.Name); string desc = NamingUtil.GetDescriptionOverride(systemElem, null); - string objectType = NamingUtil.GetObjectTypeOverride(systemElem, - (systemElemType != null) ? systemElemType.Name : ""); + string objectType = NamingUtil.GetObjectTypeOverride(systemElem, systemElemType?.Name ?? string.Empty); string systemGUID = GUIDUtil.CreateGUID(systemElem); IFCAnyHandle systemHandle = null; @@ -5044,7 +4018,7 @@ private bool RememberWCSOrGeoReference (double eastings, double northings, doubl string ifcEnumType; IFCExportInfoPair exportAs = ExporterUtil.GetObjectExportType(exporterIFC, systemElem, out ifcEnumType); - string predefinedType = exportAs.ValidatedPredefinedType; + string predefinedType = exportAs.PredefinedType; if (predefinedType == null) { Toolkit.IFC4.IFCDistributionSystem systemType = ConnectorExporter.GetMappedIFCDistributionSystemFromElement(systemElem); diff --git a/Source/Revit.IFC.Export/Exporter/ExporterInitializer.cs b/Source/Revit.IFC.Export/Exporter/ExporterInitializer.cs index 59342d9e..7a0be1c2 100644 --- a/Source/Revit.IFC.Export/Exporter/ExporterInitializer.cs +++ b/Source/Revit.IFC.Export/Exporter/ExporterInitializer.cs @@ -25,7 +25,6 @@ using Revit.IFC.Export.Utility; using Revit.IFC.Common.Enums; using Revit.IFC.Common.Utility; -using GeometryGym.Ifc; namespace Revit.IFC.Export.Exporter { @@ -189,231 +188,85 @@ private static void InitUserDefinedPropertySets(IList quantityDescriptions = new List(); // get the Pset definitions (using the same file as PropertyMap) - IEnumerable userDefinedPsetDefs = PropertyMap.LoadUserDefinedPset(); - PropertyValueType propValueType = PropertyValueType.SingleValue; - + IEnumerable userDefinedPsetDefs = PropertyMap.LoadUserDefinedPset(); bool exportPre4 = (ExporterCacheManager.ExportOptionsCache.ExportAs2x2 || ExporterCacheManager.ExportOptionsCache.ExportAs2x3); // Loop through each definition and add the Pset entries into Cache - foreach (IfcPropertySetTemplate psetDef in userDefinedPsetDefs) + foreach (UserDefinedPropertySet propertySet in userDefinedPsetDefs) { // Add Propertyset entry Description description = null; - BuiltInParameter builtInParameter = BuiltInParameter.INVALID; - if (string.Compare(psetDef.Name, "Attribute Mapping", true) == 0) + if (string.Compare(propertySet.Name, "Attribute Mapping", true) == 0) { AttributeSetDescription attributeDescription = new AttributeSetDescription(); ExporterCacheManager.AttributeCache.AddAttributeSet(attributeDescription); - foreach (IfcPropertyTemplate prop in psetDef.HasPropertyTemplates.Values) + foreach (UserDefinedProperty property in propertySet.Properties) { - IfcSimplePropertyTemplate template = prop as IfcSimplePropertyTemplate; - if (template != null) - { - PropertyType dataType; - if (!Enum.TryParse(template.PrimaryMeasureType.ToLower().Replace("ifc", ""), true, out dataType)) - { - dataType = PropertyType.Text; - } - List mappings = new List(); - foreach (IfcRelAssociates associates in template.HasAssociations) - { - IfcRelAssociatesClassification associatesClassification = associates as IfcRelAssociatesClassification; - if (associatesClassification != null) - { - IfcClassificationReference classificationReference = associatesClassification.RelatingClassification as IfcClassificationReference; - if (classificationReference != null) - { - string id = classificationReference.Identification; - if (id.ToLower().StartsWith("builtinparameter.")) - { - id = id.Substring("BuiltInParameter.".Length); - if (Enum.TryParse(id, out builtInParameter) && builtInParameter != Autodesk.Revit.DB.BuiltInParameter.INVALID) - { - mappings.Add(new AttributeEntryMap(template.Name, builtInParameter)); - } - else - { - // report as error in log when we create log file. - } - } - else - mappings.Add(new AttributeEntryMap(id, BuiltInParameter.INVALID)); - } - } - } - - AttributeEntry aSE = new AttributeEntry(template.Name, dataType, mappings); - attributeDescription.AddEntry(aSE); - } + // Data types to export is not provided or invalid. + if ((property.IfcPropertyTypes?.Count ?? 0) == 0) + continue; + + PropertyType dataType = property.FirstIfcPropertyTypeOrDefault(PropertyType.Text); + List entryMap = property.GetEntryMap((name, parameter) => new AttributeEntryMap(name, parameter)); + AttributeEntry aSE = new AttributeEntry(property.Name, dataType, entryMap); + attributeDescription.AddEntry(aSE); } - description = attributeDescription; + description = attributeDescription; } - else if (psetDef.TemplateType == IfcPropertySetTemplateTypeEnum.QTO_OCCURRENCEDRIVEN || psetDef.TemplateType == IfcPropertySetTemplateTypeEnum.QTO_TYPEDRIVENONLY || psetDef.TemplateType == IfcPropertySetTemplateTypeEnum.QTO_TYPEDRIVENOVERRIDE) + else if (propertySet.Type?.StartsWith("Qto_", StringComparison.InvariantCultureIgnoreCase) ?? false) { QuantityDescription quantityDescription = new QuantityDescription(); quantityDescriptions.Add(quantityDescription); description = quantityDescription; - foreach (IfcPropertyTemplate prop in psetDef.HasPropertyTemplates.Values) + foreach (UserDefinedProperty property in propertySet.Properties) { - IfcSimplePropertyTemplate template = prop as IfcSimplePropertyTemplate; - if (template != null) - { - List mappings = new List(); - foreach (IfcRelAssociates associates in template.HasAssociations) - { - IfcRelAssociatesClassification associatesClassification = associates as IfcRelAssociatesClassification; - if (associatesClassification != null) - { - IfcClassificationReference classificationReference = associatesClassification.RelatingClassification as IfcClassificationReference; - if (classificationReference != null) - { - string id = classificationReference.Identification; - if (id.ToLower().StartsWith("builtinparameter.")) - { - id = id.Substring("BuiltInParameter.".Length); - if (Enum.TryParse(id, out builtInParameter) && builtInParameter != Autodesk.Revit.DB.BuiltInParameter.INVALID) - { - mappings.Add(new QuantityEntryMap(template.Name, builtInParameter)); - } - else - { - // report as error in log when we create log file. - } - } - else - mappings.Add(new QuantityEntryMap(id, BuiltInParameter.INVALID)); - } - } - } - QuantityType quantityType = QuantityType.Real; - switch (template.TemplateType) - { - case IfcSimplePropertyTemplateTypeEnum.Q_AREA: - quantityType = QuantityType.Area; - break; - case IfcSimplePropertyTemplateTypeEnum.Q_LENGTH: - quantityType = QuantityType.PositiveLength; - break; - case IfcSimplePropertyTemplateTypeEnum.Q_VOLUME: - quantityType = QuantityType.Volume; - break; - case IfcSimplePropertyTemplateTypeEnum.Q_WEIGHT: - quantityType = QuantityType.Weight; - break; - default: - quantityType = QuantityType.Real; - break; - } - QuantityEntry quantityEntry = new QuantityEntry(prop.Name, mappings) { QuantityType = quantityType }; - quantityDescription.AddEntry(quantityEntry); - } + // Data types to export is not provided or invalid. + if ((property.IfcPropertyTypes?.Count ?? 0) == 0) + continue; + + QuantityType quantityType = property.FirstIfcPropertyTypeOrDefault(QuantityType.Real); + IList entryMap = property.GetEntryMap((name, parameter) => new QuantityEntryMap(name, parameter)); + QuantityEntry quantityEntry = new QuantityEntry(property.Name, entryMap) { QuantityType = quantityType }; + quantityDescription.AddEntry(quantityEntry); } } else { PropertySetDescription userDefinedPropertySet = new PropertySetDescription(); description = userDefinedPropertySet; - foreach (IfcPropertyTemplate prop in psetDef.HasPropertyTemplates.Values) + foreach(UserDefinedProperty property in propertySet.Properties) { - IfcSimplePropertyTemplate template = prop as IfcSimplePropertyTemplate; - if (template != null) + PropertyType primaryType = property.FirstIfcPropertyTypeOrDefault(PropertyType.Text); // force default to Text/string if the type does not match with any correct datatype + PropertyType secondaryType = property.GetIfcPropertyAtOrDefault(1, PropertyType.Text); + IList entryMap = property.GetEntryMap((name, parameter) => new PropertySetEntryMap(name, parameter)); + if (entryMap.Count > 0) { - IfcValue defaultValue = null; - PropertyType dataType; - if (!Enum.TryParse(template.PrimaryMeasureType.ToLower().Replace("ifc", ""), true, out dataType)) - { - dataType = PropertyType.Text; // force default to Text/string if the type does not match with any correct datatype - } - - PropertyType secondaryDataType; - if (!Enum.TryParse(template.SecondaryMeasureType.ToLower().Replace("ifc", ""), true, out secondaryDataType)) - { - secondaryDataType = PropertyType.Text; // force default to Text/string if the type does not match with any correct datatype - } - List mappings = new List(); - foreach (IfcRelAssociates associates in template.HasAssociations) - { - IfcRelAssociatesClassification associatesClassification = associates as IfcRelAssociatesClassification; - if (associatesClassification != null) - { - IfcClassificationReference classificationReference = associatesClassification.RelatingClassification as IfcClassificationReference; - if (classificationReference != null) - { - string id = classificationReference.Identification; - if (id.ToLower().StartsWith("builtinparameter.")) - { - id = id.Substring("BuiltInParameter.".Length); - if (Enum.TryParse(id, out builtInParameter) && builtInParameter != Autodesk.Revit.DB.BuiltInParameter.INVALID) - { - mappings.Add(new PropertySetEntryMap(template.Name, builtInParameter)); - } - else - { - // report as error in log when we create log file. - } - } - else - mappings.Add(new PropertySetEntryMap(id, BuiltInParameter.INVALID)); - } - } - else - { - IfcRelAssociatesConstraint associatesConstraint = associates as IfcRelAssociatesConstraint; - if (associatesConstraint != null) - { - IfcMetric metric = associatesConstraint.RelatingConstraint as IfcMetric; - if (metric != null) - { - defaultValue = metric.DataValue as IfcValue; - } - } - } - } - if (mappings.Count > 0) - { - PropertySetEntry pSE = new PropertySetEntry(dataType, prop.Name, mappings); - pSE.DefaultValue = defaultValue; - userDefinedPropertySet.AddEntry(pSE); - } - else + PropertySetEntry propertySetEntry = new PropertySetEntry(primaryType, property.Name, entryMap); + userDefinedPropertySet.AddEntry(propertySetEntry); + } + else + { + PropertySetEntry propertySetEntry = new PropertySetEntry(property.Name) { - switch (template.TemplateType) - { - case IfcSimplePropertyTemplateTypeEnum.P_LISTVALUE: - propValueType = PropertyValueType.ListValue; - break; - case IfcSimplePropertyTemplateTypeEnum.P_BOUNDEDVALUE: - propValueType = PropertyValueType.BoundedValue; - break; - case IfcSimplePropertyTemplateTypeEnum.P_TABLEVALUE: - propValueType = PropertyValueType.TableValue; - break; - default: - propValueType = PropertyValueType.SingleValue; - break; - } - - PropertySetEntry pSE = new PropertySetEntry(prop.Name); - pSE.PropertyName = prop.Name; - pSE.PropertyType = dataType; - pSE.PropertyArgumentType = secondaryDataType; - pSE.DefaultValue = defaultValue; - pSE.PropertyValueType = propValueType; - userDefinedPropertySet.AddEntry(pSE); - } + PropertyName = property.Name, + PropertyType = primaryType, + PropertyArgumentType = secondaryType, + PropertyValueType = property.IfcPropertyValueType + }; + userDefinedPropertySet.AddEntry(propertySetEntry); } } + userDefinedPropertySets.Add(userDefinedPropertySet); } - description.Name = psetDef.Name; - description.DescriptionOfSet = psetDef.Description; - string[] applicableElements = psetDef.ApplicableEntity.Split(",".ToCharArray()); - foreach (string elem in applicableElements) + description.Name = propertySet.Name; + description.DescriptionOfSet = string.Empty; + + foreach (string elem in propertySet.IfcEntities) { - Common.Enums.IFCEntityType ifcEntity; - if (Enum.TryParse(elem, out ifcEntity)) + if (Enum.TryParse(elem, out IFCEntityType ifcEntity)) { bool usedCompatibleType = false; @@ -445,7 +298,6 @@ private static void InitUserDefinedPropertySets(IList 0) ExporterCacheManager.ParameterCache.Quantities.Add(quantityDescriptions); - } private static bool IsSupportedFieldType(ScheduleFieldType fieldType) diff --git a/Source/Revit.IFC.Export/Exporter/ExtrusionExporter.cs b/Source/Revit.IFC.Export/Exporter/ExtrusionExporter.cs index 146f13b2..7895cb67 100644 --- a/Source/Revit.IFC.Export/Exporter/ExtrusionExporter.cs +++ b/Source/Revit.IFC.Export/Exporter/ExtrusionExporter.cs @@ -278,8 +278,7 @@ private static bool GetCenterAndRadiusOfCurveLoop(CurveLoop curveLoop, out XYZ c private static IFCAnyHandle CreateCircleBasedProfileDefIfPossible(ExporterIFC exporterIFC, string profileName, CurveLoop curveLoop, Transform lcs, XYZ projDir) { - IList curveLoops = new List(); - curveLoops.Add(curveLoop); + IList curveLoops = new List() { curveLoop }; return CreateCircleBasedProfileDefIfPossible(exporterIFC, profileName, curveLoops, lcs, projDir); } @@ -334,58 +333,24 @@ private static bool GetCenterAndRadiusOfCurveLoop(CurveLoop curveLoop, out XYZ c if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView) { - XYZ xDir = lcs.BasisX; - XYZ yDir = lcs.BasisY; - XYZ zDir = lcs.BasisZ; - XYZ orig = lcs.Origin; - - ctr -= orig; - - IList newCtr = new List(); - newCtr.Add(UnitUtil.ScaleLength(xDir.DotProduct(ctr))); - newCtr.Add(UnitUtil.ScaleLength(yDir.DotProduct(ctr))); - newCtr.Add(UnitUtil.ScaleLength(zDir.DotProduct(ctr))); - - IFCAnyHandle location = IFCInstanceExporter.CreateCartesianPoint(file, newCtr); - XYZ projDirToUse = projDir; - XYZ refDirToUse = new XYZ(1.0, 0.0, 0.0); if (curveLoops[0].HasPlane()) { projDirToUse = curveLoops[0].GetPlane().Normal; - refDirToUse = curveLoops[0].GetPlane().XVec; } - IList axisDir = new List(); - axisDir.Add(projDirToUse.X); - axisDir.Add(projDirToUse.Y); - axisDir.Add(projDirToUse.Z); - IFCAnyHandle axisDirectionOpt = ExporterUtil.CreateDirection(file, axisDir); - - IList refDir = new List(); - refDir.Add(1.0); - refDir.Add(0.0); - refDir.Add(0.0); - IFCAnyHandle refDirectionOpt = ExporterUtil.CreateDirection(file, refDirToUse); - - IFCAnyHandle defPosition = IFCInstanceExporter.CreateAxis2Placement3D(file, location, axisDirectionOpt, refDirectionOpt); - IFCAnyHandle outerCurve = GeometryUtil.CreateIFCCurveFromCurveLoop(exporterIFC, curveLoops[0], lcs, projDirToUse); - //if (MathUtil.IsAlmostZero(innerRadius)) if (numLoops == 1) - return IFCInstanceExporter.CreateArbitraryClosedProfileDef(file, IFCProfileType.Area, profileName, outerCurve); - else { - IFCAnyHandle innerCurve = GeometryUtil.CreateIFCCurveFromCurveLoop(exporterIFC, curveLoops[1], lcs, projDirToUse); - HashSet innerCurves = new HashSet(); - innerCurves.Add(innerCurve); - return IFCInstanceExporter.CreateArbitraryProfileDefWithVoids(file, IFCProfileType.Area, profileName, outerCurve, innerCurves); + return IFCInstanceExporter.CreateArbitraryClosedProfileDef(file, IFCProfileType.Area, profileName, outerCurve); } + + IFCAnyHandle innerCurve = GeometryUtil.CreateIFCCurveFromCurveLoop(exporterIFC, curveLoops[1], lcs, projDirToUse); + HashSet innerCurves = new HashSet() { innerCurve }; + return IFCInstanceExporter.CreateArbitraryProfileDefWithVoids(file, IFCProfileType.Area, profileName, outerCurve, innerCurves); } else { - IList arcs = new List(); - if (numLoops == 2) { XYZ checkCtr; @@ -404,23 +369,25 @@ private static bool GetCenterAndRadiusOfCurveLoop(CurveLoop curveLoop, out XYZ c ctr -= orig; - IList newCtr = new List(); - newCtr.Add(UnitUtil.ScaleLength(xDir.DotProduct(ctr))); - newCtr.Add(UnitUtil.ScaleLength(yDir.DotProduct(ctr))); + IList newCtr = new List() + { + UnitUtil.ScaleLength(xDir.DotProduct(ctr)), + UnitUtil.ScaleLength(yDir.DotProduct(ctr)) + }; IFCAnyHandle location = IFCInstanceExporter.CreateCartesianPoint(file, newCtr); - IList refDir = new List(); - refDir.Add(1.0); - refDir.Add(0.0); + IList refDir = new List() { 1.0, 0.0 }; IFCAnyHandle refDirectionOpt = ExporterUtil.CreateDirection(file, refDir); IFCAnyHandle defPosition = IFCInstanceExporter.CreateAxis2Placement2D(file, location, null, refDirectionOpt); if (MathUtil.IsAlmostZero(innerRadius)) + { return IFCInstanceExporter.CreateCircleProfileDef(file, IFCProfileType.Area, profileName, defPosition, radius); - else - return IFCInstanceExporter.CreateCircleHollowProfileDef(file, IFCProfileType.Area, profileName, defPosition, radius, radius - innerRadius); + } + + return IFCInstanceExporter.CreateCircleHollowProfileDef(file, IFCProfileType.Area, profileName, defPosition, radius, radius - innerRadius); } } @@ -723,17 +690,22 @@ private static bool GetCenterAndRadiusOfCurveLoop(CurveLoop curveLoop, out XYZ c overallWidth, overallDepth, webThickness, flangeThickness, filletRadius); } + /// + /// Check to see if a curve loop is oriented clockwise. + /// + /// The curve loop to check. + /// The direction to compare against. /// true if the curve loop is clockwise, false otherwise. - private static bool SafeIsCurveLoopClockwise(CurveLoop curveLoop, XYZ dir) + private static bool? SafeIsCurveLoopClockwise(CurveLoop curveLoop, XYZ dir) { if (curveLoop == null) - return false; + return null; if (curveLoop.IsOpen()) - return false; + return null; if ((curveLoop.Count() == 1) && !(curveLoop.First().IsBound)) - return false; + return null; return !curveLoop.IsCounterclockwise(dir); } @@ -745,7 +717,7 @@ private static bool SafeIsCurveLoopClockwise(CurveLoop curveLoop, XYZ dir) /// Extrusion direction /// Output parameter for the "corrected" LCS /// True if the LCS is set - private static bool CorrectCurveLoopOrientation(IList curveLoops, XYZ extrDir, out Transform lcs) + public static bool CorrectCurveLoopOrientation(IList curveLoops, XYZ extrDir, out Transform lcs) { lcs = null; int loopSz = curveLoops.Count; @@ -773,8 +745,10 @@ private static bool CorrectCurveLoopOrientation(IList curveLoops, XYZ } else if (firstCurve) { - if (SafeIsCurveLoopClockwise(curveLoop, extrDir)) + if (SafeIsCurveLoopClockwise(curveLoop, extrDir).GetValueOrDefault(false)) + { curveLoop.Flip(); + } try { @@ -790,8 +764,10 @@ private static bool CorrectCurveLoopOrientation(IList curveLoops, XYZ } else { - if (!SafeIsCurveLoopClockwise(curveLoop, extrDir)) + if (!SafeIsCurveLoopClockwise(curveLoop, extrDir).GetValueOrDefault(true)) + { curveLoop.Flip(); + } } firstCurve = false; @@ -1069,9 +1045,8 @@ public static IFCAnyHandle CreateSweptArea(ExporterIFC exporterIFC, string profi { if (isCCW) curveLoop.Flip(); - IFCAnyHandle innerCurve = GeometryUtil.CreateIFCCurveFromCurveLoop(exporterIFC, curveLoop, lcs, sweptDirection); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(innerCurve)) - innerCurves.Add(innerCurve); + innerCurves.AddIfNotNull(GeometryUtil.CreateIFCCurveFromCurveLoop( + exporterIFC, curveLoop, lcs, sweptDirection)); } } @@ -1897,11 +1872,9 @@ private static bool AllowMultipleClipPlanesForCategory(ElementId cuttingElementC // A list of IfcCurve entities. if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView) { - IFCAnyHandle curveHnd = GeometryUtil.CreatePolyCurveFromCurve(exporterIFC, baseCurve, - extrusionLCS, extrusionDir); profileCurves = new List(); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(curveHnd)) - profileCurves.Add(curveHnd); + profileCurves.AddIfNotNull(GeometryUtil.CreatePolyCurveFromCurve(exporterIFC, + baseCurve, extrusionLCS, extrusionDir)); } else { diff --git a/Source/Revit.IFC.Export/Exporter/FamilyInstanceExporter.cs b/Source/Revit.IFC.Export/Exporter/FamilyInstanceExporter.cs index 41185fc2..8fac0e04 100644 --- a/Source/Revit.IFC.Export/Exporter/FamilyInstanceExporter.cs +++ b/Source/Revit.IFC.Export/Exporter/FamilyInstanceExporter.cs @@ -156,14 +156,13 @@ private static bool IsExtrusionFriendlyType(IFCEntityType entityType) using (IFCTransaction tr = new IFCTransaction(file)) { - string ifcEnumType; - IFCExportInfoPair exportType = ExporterUtil.GetProductExportType(exporterIFC, familyInstance, out ifcEnumType); + IFCExportInfoPair exportType = ExporterUtil.GetProductExportType(exporterIFC, familyInstance, out _); if (exportType.IsUnKnown) return; // TODO: This step now appears to be redundant with the rest of the steps, but to change it is too much of risk of regression. Reserve it for future refactoring - if (ExportGenericToSpecificElement(exporterIFC, familyInstance, ref geometryElement, exportType, ifcEnumType, productWrapper)) + if (ExportGenericToSpecificElement(exporterIFC, familyInstance, ref geometryElement, exportType, productWrapper)) { tr.Commit(); return; @@ -176,7 +175,7 @@ private static bool IsExtrusionFriendlyType(IFCEntityType entityType) // We will not split walls and columns if the assemblyId is set, as we would like to keep the original wall // associated with the assembly, on the level of the assembly. bool splitColumn = (exportType.ExportInstance == IFCEntityType.IfcColumn) && (ExporterCacheManager.ExportOptionsCache.WallAndColumnSplitting) && - (familyInstance.AssemblyInstanceId == ElementId.InvalidElementId); + !ExporterUtil.IsContainedInAssembly(familyInstance); if (splitColumn) { LevelUtil.CreateSplitLevelRangesForElement(exporterIFC, exportType, familyInstance, out levels, out ranges); @@ -185,7 +184,7 @@ private static bool IsExtrusionFriendlyType(IFCEntityType entityType) int numPartsToExport = ranges.Count; if (numPartsToExport == 0) { - ExportFamilyInstanceAsMappedItem(exporterIFC, familyInstance, exportType, ifcEnumType, productWrapper, + ExportFamilyInstanceAsMappedItem(exporterIFC, familyInstance, exportType, productWrapper, ElementId.InvalidElementId, null, null); } else @@ -195,7 +194,7 @@ private static bool IsExtrusionFriendlyType(IFCEntityType entityType) for (int ii = 0; ii < numPartsToExport; ii++) { rangeSetter.IncreaseRangeIndex(); - ExportFamilyInstanceAsMappedItem(exporterIFC, familyInstance, exportType, ifcEnumType, productWrapper, + ExportFamilyInstanceAsMappedItem(exporterIFC, familyInstance, exportType, productWrapper, levels[ii], ranges[ii], null); } } @@ -208,7 +207,7 @@ private static bool IsExtrusionFriendlyType(IFCEntityType entityType) foreach (KeyValuePair levelRange in levelRangeList) { rangeSetter.IncreaseRangeIndex(); - ExportFamilyInstanceAsMappedItem(exporterIFC, familyInstance, exportType, ifcEnumType, productWrapper, levelRange.Key, levelRange.Value, null); + ExportFamilyInstanceAsMappedItem(exporterIFC, familyInstance, exportType, productWrapper, levelRange.Key, levelRange.Value, null); } } } @@ -231,7 +230,7 @@ private static bool IsExtrusionFriendlyType(IFCEntityType entityType) /// The instance element. /// The type element. /// For FamilyInstances, the primary symbol. - /// True if we should ues the instance geometry. + /// True if we should use the instance geometry. /// True if we are exporting parts. /// The entity type information. /// The created list of property sets. @@ -239,7 +238,7 @@ private static bool IsExtrusionFriendlyType(IFCEntityType entityType) public static IFCAnyHandle CreateTypeEntityHandle(ExporterIFC exporterIFC, TypeObjectKey typeKey, ref FamilyTypeInfo typeInfo, DoorWindowInfo doorWindowInfo, IList representations3D, IList trfRepMapList, - IList representations2D, Element familyInstance, ElementType familySymbol, + IList representations2D, IDictionary trfRep2DMapList, Element familyInstance, ElementType familySymbol, ElementType originalFamilySymbol, ElementId overrideLevelId, bool useInstanceGeometry, bool exportParts, IFCExportInfoPair exportType, out HashSet propertySets) { @@ -254,15 +253,22 @@ private static bool IsExtrusionFriendlyType(IFCEntityType entityType) IList repMapList = new List(); { IFCAnyHandle origin = null; + int originTransformIndex = -1; if (representations3D != null) { int num = 0; foreach (IFCAnyHandle rep in representations3D) { if (trfRepMapList[num] == null) + { + originTransformIndex = -1; origin = ExporterUtil.CreateAxis2Placement3D(file); + } else + { + originTransformIndex = num; origin = ExporterUtil.CreateAxis2Placement3D(file, trfRepMapList[num].Origin, trfRepMapList[num].BasisZ, trfRepMapList[num].BasisX); // Used by 'Axis' MappedRepresentation + } repMap3dHnd = IFCInstanceExporter.CreateRepresentationMap(file, origin, rep); repMapList.Add(repMap3dHnd); @@ -276,7 +282,17 @@ private static bool IsExtrusionFriendlyType(IFCEntityType entityType) origin = ExporterUtil.CreateAxis2Placement3D(file); foreach (IFCAnyHandle rep in representations2D) { - repMap2dHnd = IFCInstanceExporter.CreateRepresentationMap(file, origin, rep); + IFCAnyHandle currentOrigin = origin; + if (trfRep2DMapList?.TryGetValue(rep, out Transform rep2DTransform) ?? false) + { + // Add 3D represantation origin transform if set. + if (originTransformIndex >= 0) + rep2DTransform = trfRepMapList[originTransformIndex].Multiply(rep2DTransform); + + currentOrigin = ExporterUtil.CreateAxis2Placement3D(file, rep2DTransform.Origin, rep2DTransform.BasisZ, rep2DTransform.BasisX); + } + + repMap2dHnd = IFCInstanceExporter.CreateRepresentationMap(file, currentOrigin, rep); repMapList.Add(repMap2dHnd); } } @@ -309,37 +325,28 @@ private static bool IsExtrusionFriendlyType(IFCEntityType entityType) { case IFCEntityType.IfcBeam: { - string beamType = exportType.ValidatedPredefinedType; - if (string.IsNullOrEmpty(beamType) || beamType.Equals("NOTDEFINED", StringComparison.InvariantCultureIgnoreCase)) - beamType = "Beam"; - typeStyle = IFCInstanceExporter.CreateBeamType(file, familySymbol, guid, - propertySets, repMapList, beamType); + string beamType = exportType.GetPredefinedTypeOrDefault("Beam"); + typeStyle = IFCInstanceExporter.CreateBeamType(file, familySymbol, guid, propertySets, repMapList, beamType); break; } case IFCEntityType.IfcColumn: { - string columnType = exportType.ValidatedPredefinedType; - if (string.IsNullOrEmpty(columnType) || columnType.Equals("NOTDEFINED", StringComparison.InvariantCultureIgnoreCase)) - columnType = "Column"; + string columnType = exportType.GetPredefinedTypeOrDefault("Column"); typeStyle = IFCInstanceExporter.CreateColumnType(file, familySymbol, guid, propertySets, repMapList, columnType); break; } case IFCEntityType.IfcMember: { - string memberType = exportType.ValidatedPredefinedType; - if (string.IsNullOrEmpty(memberType) || memberType.Equals("NOTDEFINED", StringComparison.InvariantCultureIgnoreCase)) - memberType = "Brace"; + string memberType = exportType.GetPredefinedTypeOrDefault("Brace"); typeStyle = IFCInstanceExporter.CreateMemberType(file, familySymbol, guid, propertySets, repMapList, memberType); break; } case IFCEntityType.IfcDoor: { - IFCAnyHandle doorLining = DoorWindowUtil.CreateDoorLiningProperties(exporterIFC, - familyInstance); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(doorLining)) - propertySets.Add(doorLining); + propertySets.AddIfNotNull(DoorWindowUtil.CreateDoorLiningProperties( + exporterIFC, familyInstance)); IList doorPanels = DoorWindowUtil.CreateDoorPanelProperties(exporterIFC, doorWindowInfo, familyInstance); @@ -364,13 +371,13 @@ private static bool IsExtrusionFriendlyType(IFCEntityType entityType) case IFCEntityType.IfcSpace: { typeStyle = IFCInstanceExporter.CreateSpaceType(file, familySymbol, guid, - propertySets, repMapList, exportType.ValidatedPredefinedType); + propertySets, repMapList, exportType.GetPredefinedTypeOrDefault()); break; } case IFCEntityType.IfcSystemFurnitureElement: { typeStyle = IFCInstanceExporter.CreateSystemFurnitureElementType(file, - familySymbol, guid, propertySets, repMapList, exportType.ValidatedPredefinedType); + familySymbol, guid, propertySets, repMapList, exportType.GetPredefinedTypeOrDefault()); break; } case IFCEntityType.IfcWindow: @@ -378,9 +385,8 @@ private static bool IsExtrusionFriendlyType(IFCEntityType entityType) IFCWindowStyleOperation operationType = DoorWindowUtil.GetIFCWindowStyleOperation(originalFamilySymbol); IFCWindowStyleConstruction constructionType = DoorWindowUtil.GetIFCWindowStyleConstruction(familyInstance); - IFCAnyHandle windowLining = DoorWindowUtil.CreateWindowLiningProperties(exporterIFC, familyInstance, null); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(windowLining)) - propertySets.Add(windowLining); + propertySets.AddIfNotNull(DoorWindowUtil.CreateWindowLiningProperties( + exporterIFC, familyInstance, null)); IList windowPanels = DoorWindowUtil.CreateWindowPanelProperties(exporterIFC, familyInstance, null); @@ -412,7 +418,7 @@ private static bool IsExtrusionFriendlyType(IFCEntityType entityType) { typeStyle = IFCInstanceExporter.CreateFurnitureType(file, familySymbol, guid, propertySets, repMapList, null, null, null, - exportType.ValidatedPredefinedType); + exportType.GetPredefinedTypeOrDefault()); break; } } @@ -429,9 +435,7 @@ private static bool IsExtrusionFriendlyType(IFCEntityType entityType) if (IFCAnyHandleUtil.IsNullOrHasNoValue(typeStyle)) { // This covers many generic types. If we can't find it in the list here, do custom exports. - typeStyle = FamilyExporterUtil.ExportGenericType(exporterIFC, exportType, - exportType.ValidatedPredefinedType, propertySets, repMapList, familyInstance, - familySymbol, guid); + typeStyle = FamilyExporterUtil.ExportGenericType(exporterIFC, exportType, propertySets, repMapList, familyInstance, familySymbol, guid); } if (IFCAnyHandleUtil.IsNullOrHasNoValue(typeStyle)) @@ -453,6 +457,15 @@ private static bool IsExtrusionFriendlyType(IFCEntityType entityType) , new ElementId(BuiltInCategory.OST_PipeCurves) , new ElementId(BuiltInCategory.OST_PipeFitting) }; + + private static readonly HashSet s_LinedOnlySet = new HashSet() + { + new ElementId(BuiltInCategory.OST_DuctAccessory) + , new ElementId(BuiltInCategory.OST_DuctCurves) + , new ElementId(BuiltInCategory.OST_DuctFitting) + , new ElementId(BuiltInCategory.OST_FlexDuctCurves) + }; + private static bool CanHaveInsulationOrLining(IFCExportInfoPair exportType, ElementId categoryId) { // This is intended to reduce the number of exceptions thrown in GetLiningIds and GetInsulationIds. @@ -464,6 +477,16 @@ private static bool CanHaveInsulationOrLining(IFCExportInfoPair exportType, Elem return s_InsulatedOrLinedSet.Contains(categoryId); } + /// + /// Checks if a given category is compatible with having insulation. + /// + /// The category id. + /// True if it supports insulation, false otherwise. + public static bool CategoryCanHaveLining(ElementId categoryId) + { + return s_LinedOnlySet.Contains(categoryId); + } + private static bool CanHaveSystemDefinition(IFCExportInfoPair exportType, ElementId categoryId) { if (exportType.ExportType != IFCEntityType.IfcCableSegmentType && exportType.ExportType != IFCEntityType.IfcCableCarrierSegmentType && @@ -512,12 +535,11 @@ private static bool IsTransformValid(Transform transform) /// The ExporterIFC object. /// The family instance to be exported. /// The export type. - /// The string value represents the IFC type. /// The ProductWrapper. /// The level id. /// The range of this family instance to be exported. public static void ExportFamilyInstanceAsMappedItem(ExporterIFC exporterIFC, FamilyInstance familyInstance, IFCExportInfoPair exportType, - string ifcEnumType, ProductWrapper wrapper, ElementId overrideLevelId, IFCRange range, IFCAnyHandle parentLocalPlacement) + ProductWrapper wrapper, ElementId overrideLevelId, IFCRange range, IFCAnyHandle parentLocalPlacement) { bool exportParts = PartExporter.CanExportParts(familyInstance); bool isSplit = range != null; @@ -561,6 +583,7 @@ private static bool IsTransformValid(Transform transform) IFCExportBodyParams extrusionData = null; IList repMapTrfList = new List(); + IDictionary repMap2DTrfDict = new Dictionary(); XYZ orig = XYZ.Zero; XYZ extrudeDirection = null; @@ -577,7 +600,7 @@ private static bool IsTransformValid(Transform transform) FamilyTypeInfo typeInfo = new FamilyTypeInfo(); IFCExportBodyParams extraParams = typeInfo.extraParams; - exportType = FamilyExporterUtil.AdjustExportTypeForSchema(exportType, exportType.ValidatedPredefinedType); + exportType = FamilyExporterUtil.AdjustExportTypeForSchema(exportType); bool flipped = doorWindowInfo?.FlippedSymbol ?? false; ElementId overrideMaterialId = ExporterUtil.GetSingleMaterial(familyInstance); @@ -688,7 +711,7 @@ private static bool IsTransformValid(Transform transform) // Get a profile name. string profileName = NamingUtil.GetProfileName(familySymbol); - StructuralMemberAxisInfo axisInfo = StructuralMemberExporter.GetStructuralMemberAxisTransform(familyInstance); + StructuralMemberAxisInfo axisInfo = StructuralMemberExporter.GetStructuralMemberAxisTransform(exportGeometryElement); if (axisInfo != null) { orig = axisInfo.LCSAsTransform.Origin; @@ -728,9 +751,8 @@ private static bool IsTransformValid(Transform transform) } typeInfo.MaterialIdList = extraClippingData.MaterialIds; - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRepresentation)) + if (representations3D.AddIfNotNull(bodyRepresentation)) { - representations3D.Add(bodyRepresentation); repMapTrfList.Add(null); if (materialAndProfile != null) typeInfo.MaterialAndProfile = materialAndProfile; // Keep material and profile information in the type info for later creation @@ -757,9 +779,8 @@ private static bool IsTransformValid(Transform transform) ElementId catId = CategoryUtil.GetSafeCategoryId(familyInstance); IFCAnyHandle axisRep = StructuralMemberExporter.CreateStructuralMemberAxis(exporterIFC, familyInstance, catId, axisInfo, newLCS); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(axisRep)) + if (representations3D.AddIfNotNull(axisRep)) { - representations3D.Add(axisRep); // This offset is going to be applied later. Need to scale the coordinate into the correct unit scale offset.Origin = UnitUtil.ScaleLength(offset.Origin); repMapTrfList.Add(offset); @@ -797,9 +818,8 @@ private static bool IsTransformValid(Transform transform) offsetTransform = bodyData.OffsetTransform; IFCAnyHandle bodyRepHnd = bodyData.RepresentationHnd; - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRepHnd)) + if (representations3D.AddIfNotNull(bodyRepHnd)) { - representations3D.Add(bodyRepHnd); repMapTrfList.Add(null); } @@ -828,9 +848,8 @@ private static bool IsTransformValid(Transform transform) ElementId catId = CategoryUtil.GetSafeCategoryId(familyInstance); IFCAnyHandle axisRep = StructuralMemberExporter.CreateStructuralMemberAxis(exporterIFC, familyInstance, catId, axisInfo, newLCS); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(axisRep)) + if (representations3D.AddIfNotNull(axisRep)) { - representations3D.Add(axisRep); repMapTrfList.Add(null); } } @@ -904,11 +923,10 @@ private static bool IsTransformValid(Transform transform) curve = curve.CreateTransformed(doorWindowTrf.Multiply(flipTrf)); } - IFCAnyHandle curveHnd = GeometryUtil.CreatePolyCurveFromCurve(exporterIFC, curve); if (curveSet == null) curveSet = new HashSet(); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(curveHnd)) - curveSet.Add(curveHnd); + curveSet.AddIfNotNull(GeometryUtil.CreatePolyCurveFromCurve( + exporterIFC, curve)); } } else @@ -925,12 +943,17 @@ private static bool IsTransformValid(Transform transform) { IFCAnyHandle contextOfItems2d = ExporterCacheManager.Get2DContextHandle(IFCRepresentationIdentifier.Annotation); IFCAnyHandle curveRepresentationItem = IFCInstanceExporter.CreateGeometricSet(file, curveSet); - HashSet bodyItems = new HashSet(); - bodyItems.Add(curveRepresentationItem); - IFCAnyHandle planRepresentation = RepresentationUtil.CreateGeometricSetRep(exporterIFC, familyInstance, categoryId, "FootPrint", - contextOfItems2d, bodyItems); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(planRepresentation)) - representations2D.Add(planRepresentation); + HashSet bodyItems = new HashSet() { curveRepresentationItem }; + IFCAnyHandle curveRep = RepresentationUtil.CreateGeometricSetRep(exporterIFC, familyInstance, categoryId, "FootPrint", contextOfItems2d, bodyItems); + + // Move 2D represantion along Z direction because the local placement of element + // can be shifted to closer to the exported geometry location. + if (representations2D.AddIfNotNull(curveRep) && !MathUtil.IsAlmostZero(curveOffset.Z)) + { + Transform moveTransform = Transform.Identity; + moveTransform.Origin = new XYZ(0, 0, UnitUtil.ScaleLength(curveOffset.Z)); + repMap2DTrfDict.Add(curveRep, moveTransform); + } } } } @@ -964,8 +987,9 @@ private static bool IsTransformValid(Transform transform) { typeStyle = CreateTypeEntityHandle(exporterIFC, typeKey, ref typeInfo, doorWindowInfo, representations3D, repMapTrfList, representations2D, - familyInstance, familySymbol, originalFamilySymbol, overrideLevelId, - useInstanceGeometry, exportParts, exportType, out propertySets); + repMap2DTrfDict, familyInstance, familySymbol, originalFamilySymbol, + overrideLevelId, useInstanceGeometry, exportParts, exportType, + out propertySets); } if (!IFCAnyHandleUtil.IsNullOrHasNoValue(typeStyle)) @@ -1120,42 +1144,51 @@ private static bool IsTransformValid(Transform transform) if ((overrideLevelId == null || overrideLevelId == ElementId.InvalidElementId) && overrideContainerId != ElementId.InvalidElementId) overrideLevelId = overrideContainerId; - if (familyInstance.AssemblyInstanceId != null && familyInstance.AssemblyInstanceId != ElementId.InvalidElementId) + if (ExporterUtil.IsContainedInAssembly(familyInstance)) { - if (ExporterCacheManager.AssemblyInstanceCache.TryGetValue(familyInstance.AssemblyInstanceId, out AssemblyInstanceInfo assInfo)) + if (overrideLevelId == ElementId.InvalidElementId) { - if (overrideLevelId == ElementId.InvalidElementId) - overrideLevelId = assInfo.AssignedLevelId; + overrideLevelId = ExporterCacheManager.LevelInfoCache.GetLevelIdOfObject(doc.GetElement(familyInstance.AssemblyInstanceId)); + } - double newOffset = trf.Origin.Z; - string shapeType = null; - foreach (IFCAnyHandle shapeRep in shapeReps) + // Determine if any of the IfcShapeRepresentations associated with this FamilyInstance are "Body" representations. + string shapeType = null; + foreach (IFCAnyHandle shapeRep in shapeReps) + { + if (IFCAnyHandleUtil.GetRepresentationIdentifier(shapeRep).Equals("Body")) { - if (IFCAnyHandleUtil.GetRepresentationIdentifier(shapeRep).Equals("Body")) - { - shapeType = IFCAnyHandleUtil.GetBaseRepresentationType(shapeRep); - } + shapeType = IFCAnyHandleUtil.GetBaseRepresentationType(shapeRep); } + } - if (!string.IsNullOrEmpty(shapeType) && (shapeType.Contains("Brep") || shapeType.Equals("Tessellation"))) + // Adjust the Origin is in the Family Instance Trf in the Z direction only. + // For BReps and Tessellations, retrieve an adjustment using the FamilySymbol origin. + XYZ adjustedOrigin = trf.Origin; + if (!string.IsNullOrEmpty(shapeType) && (shapeType.Contains("Brep") || shapeType.Equals("Tessellation"))) + { + LocationPoint loc = familyInstance.Location as LocationPoint; + if (loc != null) { - // Use LocationPoint for the offset if any as the Brep/Tessellation will have reference to it - LocationPoint loc = familyInstance.Location as LocationPoint; - if (loc != null) - { - newOffset = loc.Point.Z; - } - else + //XYZ familyInstanceAssemblyOffset = exporterIFC.GetFamilyInstanceAssemblyOffset(familyInstance); + XYZ familyInstanceAssemblyOffset = XYZ.Zero; + LocationPoint familySymbolLocation = familyInstance.Symbol.Location as LocationPoint; + if (familySymbolLocation != null) + familyInstanceAssemblyOffset = XYZ.Zero - familySymbolLocation.Point; + adjustedOrigin = new XYZ(trf.Origin.X, trf.Origin.Y, loc.Point.Z + familyInstanceAssemblyOffset.Z); + } + else + { + BoundingBoxXYZ bbox = familyInstance.get_BoundingBox(null); + if (bbox != null) { - BoundingBoxXYZ bbox = familyInstance.get_BoundingBox(null); - if (bbox != null) - { - newOffset = bbox.Min.Z; - } + adjustedOrigin = new XYZ(trf.Origin.X, trf.Origin.Y, bbox.Min.Z); } } - trf.Origin = new XYZ(trf.Origin.X, trf.Origin.Y, newOffset); + // The current trf includes a style transformation derived from ExtrusionCreationData. + // But it was not utilized for representation creation in Brep/Tessellation cases, + // using the original coordinates instead, to avoid potential incorrect coordinates. + trf.Origin = adjustedOrigin; } } @@ -1183,7 +1216,7 @@ private static bool IsTransformValid(Transform transform) GUIDUtil.CreateGUIDString(familyInstance, subElementIndex.ToString())); IFCAnyHandle overrideLocalPlacement = null; - bool isChildInContainer = familyInstance.AssemblyInstanceId != ElementId.InvalidElementId; + bool isChildInContainer = ExporterUtil.IsContainedInAssembly(familyInstance); if (parentLocalPlacement != null) { @@ -1199,16 +1232,18 @@ private static bool IsTransformValid(Transform transform) { case IFCEntityType.IfcBeam: { - if (exportType.HasUndefinedPredefinedType()) - exportType.ValidatedPredefinedType = "BEAM"; + exportType.SetPredefinedTypeIfNotDefined("BEAM"); instanceHandle = FamilyExporterUtil.ExportGenericInstance(exportType, exporterIFC, familyInstance, wrapper, setter, extraParams, instanceGUID, ownerHistory, exportParts ? null : repHnd, overrideLocalPlacement); - IFCAnyHandle placementToUse = localPlacement; + + IFCAnyHandle placementToUse = GetPlacementToUse(file, instanceHandle, localPlacement, extraParams, originalTrf, + typeInfo.StyleTransform, useInstanceGeometry); + Transform offsetTransformToUse = GetOffsetTransformtoUse(offsetTransform, setter.Offset, useInstanceGeometry); // NOTE: We do not expect openings here, as they are created as part of creating an extrusion in ExportBody above. // However, if this were the case, we would have exported this beam in ExportBeamAsStandardElement above. - OpeningUtil.CreateOpeningsIfNecessary(instanceHandle, familyInstance, extraParams, offsetTransform, + OpeningUtil.CreateOpeningsIfNecessary(instanceHandle, familyInstance, extraParams, offsetTransformToUse, exporterIFC, placementToUse, setter, wrapper); wrapper.AddElement(familyInstance, instanceHandle, setter, extraParams, true, exportType); @@ -1225,8 +1260,7 @@ private static bool IsTransformValid(Transform transform) } case IFCEntityType.IfcColumn: { - if (exportType.HasUndefinedPredefinedType()) - exportType.ValidatedPredefinedType = "COLUMN"; + exportType.SetPredefinedTypeIfNotDefined("COLUMN"); instanceHandle = FamilyExporterUtil.ExportGenericInstance(exportType, exporterIFC, familyInstance, wrapper, setter, extraParams, instanceGUID, ownerHistory, exportParts ? null : repHnd, overrideLocalPlacement); @@ -1301,14 +1335,17 @@ private static bool IsTransformValid(Transform transform) } case IFCEntityType.IfcMember: { - if (exportType.HasUndefinedPredefinedType()) - exportType.ValidatedPredefinedType = "BRACE"; + exportType.SetPredefinedTypeIfNotDefined("BRACE"); instanceHandle = FamilyExporterUtil.ExportGenericInstance(exportType, exporterIFC, familyInstance, wrapper, setter, extraParams, instanceGUID, ownerHistory, exportParts ? null : repHnd, overrideLocalPlacement); - OpeningUtil.CreateOpeningsIfNecessary(instanceHandle, familyInstance, extraParams, offsetTransform, - exporterIFC, localPlacement, setter, wrapper); + IFCAnyHandle placementToUse = GetPlacementToUse(file, instanceHandle, localPlacement, extraParams, originalTrf, + typeInfo.StyleTransform, useInstanceGeometry); + Transform offsetTransformToUse = GetOffsetTransformtoUse(offsetTransform, setter.Offset, useInstanceGeometry); + + OpeningUtil.CreateOpeningsIfNecessary(instanceHandle, familyInstance, extraParams, offsetTransformToUse, + exporterIFC, placementToUse, setter, wrapper); wrapper.AddElement(familyInstance, instanceHandle, setter, extraParams, true, exportType); if (CreateMaterialAssociation(file, instanceHandle, materialProfileSet, null)) @@ -1346,11 +1383,11 @@ private static bool IsTransformValid(Transform transform) if (!ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4) { // It is PreDefinedType attribute in IFC4 - operationType = FamilyExporterUtil.GetPreDefinedType(familyInstance, familySymbol, ifcEnumType); + operationType = FamilyExporterUtil.GetPreDefinedType(familyInstance, familySymbol, exportType.PredefinedType); } else { - operationType = FamilyExporterUtil.GetPreDefinedType(familyInstance, familySymbol, ifcEnumType); + operationType = FamilyExporterUtil.GetPreDefinedType(familyInstance, familySymbol, exportType.PredefinedType); } string operationTypeStr = operationType.ToString(); @@ -1389,7 +1426,7 @@ private static bool IsTransformValid(Transform transform) else { instanceHandle = IFCInstanceExporter.CreateBuildingElementProxy(exporterIFC, familyInstance, instanceGUID, - ownerHistory, localPlacementToUse, repHnd, exportType.ValidatedPredefinedType); + ownerHistory, localPlacementToUse, repHnd, exportType.GetPredefinedTypeOrDefault()); } bool associateToLevel = !containedInSpace && !isChildInContainer; @@ -1419,7 +1456,10 @@ private static bool IsTransformValid(Transform transform) ExporterCacheManager.MEPCache.Register(familyInstance, instanceHandle); // For ducts and pipes, check later if there is an associated duct or pipe. if (CanHaveInsulationOrLining(exportType, categoryId)) - ExporterCacheManager.MEPCache.CoveredElementsCache.Add(familyInstance.Id); + { + ExporterCacheManager.MEPCache.CoveredElementsCache[familyInstance.Id] = categoryId; + } + // For cable trays and conduits, we might create systems during the end of export. if (CanHaveSystemDefinition(exportType, categoryId)) ExporterCacheManager.MEPCache.CableElementsCache.Add(familyInstance.Id); @@ -1454,7 +1494,7 @@ private static bool IsTransformValid(Transform transform) { DoorWindowDelayedOpeningCreator delayedCreator = DoorWindowDelayedOpeningCreator.Create(exporterIFC, doorWindowInfo, instanceHandle, setter.LevelId); if (delayedCreator != null) - ExporterCacheManager.DoorWindowDelayedOpeningCreatorCache.Add(delayedCreator); + ExporterCacheManager.DoorWindowDelayedOpeningCreatorCache.Add(delayedCreator, false); } } } @@ -1465,12 +1505,11 @@ private static bool IsTransformValid(Transform transform) /// The ExporterIFC object. /// The element to be exported. /// The geometry element. - /// The export type. - /// The string value represents the IFC type. + /// The export type. /// The ProductWrapper. /// True if the elements was exported, false otherwise. static public bool ExportGenericToSpecificElement(ExporterIFC exporterIFC, Element element, ref GeometryElement geometryElement, IFCExportInfoPair exportType, - string ifcEnumTypeString, ProductWrapper productWrapper) + ProductWrapper productWrapper) { // This function is here because it was originally used exclusive by FamilyInstances. Moving forward, this will be combined with some other // functions to attempt to create a way to export any element as any IFC entity. There will still be functions that do a better job of mapping @@ -1498,10 +1537,10 @@ private static bool IsTransformValid(Transform transform) return false; } case IFCEntityType.IfcCovering: - CeilingExporter.ExportCovering(exporterIFC, element, ref geometryElement, ifcEnumTypeString, productWrapper); + CeilingExporter.ExportCovering(exporterIFC, element, ref geometryElement, exportType.PredefinedType, productWrapper); return true; case IFCEntityType.IfcRamp: - RampExporter.ExportRamp(exporterIFC, ifcEnumTypeString, element, geometryElement, 1, productWrapper); + RampExporter.ExportRamp(exporterIFC, exportType.PredefinedType, element, geometryElement, 1, productWrapper); return true; case IFCEntityType.IfcRailing: if (ExporterCacheManager.RailingCache.Contains(element.Id)) @@ -1523,14 +1562,14 @@ private static bool IsTransformValid(Transform transform) RoofExporter.ExportRoof(exporterIFC, element, ref geometryElement, productWrapper); return true; case IFCEntityType.IfcSlab: - FloorExporter.ExportGenericSlab(exporterIFC, element, geometryElement, ifcEnumTypeString, productWrapper); + FloorExporter.ExportGenericSlab(exporterIFC, element, geometryElement, exportType.PredefinedType, productWrapper); //TODO return true; case IFCEntityType.IfcStair: - StairsExporter.ExportStairAsSingleGeometry(exporterIFC, ifcEnumTypeString, element, geometryElement, new List() { 0 }, productWrapper); + StairsExporter.ExportStairAsSingleGeometry(exporterIFC, exportType.PredefinedType, element, geometryElement, new List() { 0 }, productWrapper); return true; case IFCEntityType.IfcWall: - WallExporter.ExportWall(exporterIFC, ifcEnumTypeString, element, null, ref geometryElement, productWrapper); + WallExporter.ExportWall(exporterIFC, exportType.PredefinedType, element, null, ref geometryElement, productWrapper); return true; } return false; diff --git a/Source/Revit.IFC.Export/Exporter/FilledRegionExporter.cs b/Source/Revit.IFC.Export/Exporter/FilledRegionExporter.cs index 3183e220..47055cef 100644 --- a/Source/Revit.IFC.Export/Exporter/FilledRegionExporter.cs +++ b/Source/Revit.IFC.Export/Exporter/FilledRegionExporter.cs @@ -115,7 +115,7 @@ class FilledRegionExporter HashSet bodyItems = new HashSet() { representItem }; IFCAnyHandle context2D = ExporterCacheManager.Get2DContextHandle(IFCRepresentationIdentifier.Annotation); IFCAnyHandle bodyRepHnd = RepresentationUtil.CreateAnnotationSetRep(exporterIFC, filledRegion, categoryId, - context2D, bodyItems); + context2D, bodyItems, false); if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRepHnd)) return; diff --git a/Source/Revit.IFC.Export/Exporter/FloorExporter.cs b/Source/Revit.IFC.Export/Exporter/FloorExporter.cs index 7244b144..686c8d85 100644 --- a/Source/Revit.IFC.Export/Exporter/FloorExporter.cs +++ b/Source/Revit.IFC.Export/Exporter/FloorExporter.cs @@ -261,7 +261,7 @@ class FloorExporter // For IFC4RV export, Element will be split into its parts(temporarily) in order to export the wall by its parts // If Parts are created by code and not by user then their names should be equal to Material names. bool setMaterialNameToPartName = ExporterUtil.CreateParts(floorElement, layersetInfo.MaterialIds.Count, ref geometryElement); - ExporterUtil.ExportPartAs exportPartAs = ExporterUtil.CanExportByComponentsOrParts(floorElement); + ExporterUtil.ExportPartAs exportPartAs = ExporterUtil.CanExportByComponentsOrParts(floorElement, ref geometryElement); bool exportByComponents = exportPartAs == ExporterUtil.ExportPartAs.ShapeAspect; bool exportParts = exportPartAs == ExporterUtil.ExportPartAs.Part; @@ -363,7 +363,7 @@ class FloorExporter ExtrusionExporter.ExtraClippingData extraClippingData = null; HandleAndData floorAndProperties = ExtrusionExporter.CreateExtrusionWithClippingAndProperties(exporterIFC, floorElement, false, - catId, solids[0], extrusionAnalyzerFloorBasePlane, floorOrigin, floorExtrusionDirection, null, + catId, solids[0], extrusionAnalyzerFloorBasePlane, floorOrigin, floorExtrusionDirection, null, out extraClippingData, addInfo: additionalInfo); if (extraClippingData.CompletelyClipped) @@ -383,19 +383,25 @@ class FloorExporter representations.Add(footprintShapeRep); } + IFCAnyHandle prodRep = null; if (exportByComponents) { - IFCAnyHandle prodRep = RepresentationUtil.CreateProductDefinitionShapeWithoutBodyRep(exporterIFC, floorElement, catId, geometryElement, representations); - prodReps.Add(prodRep); + prodRep = RepresentationUtil.CreateProductDefinitionShapeWithoutBodyRep(exporterIFC, floorElement, catId, geometryElement, representations); } else if (representations.Count > 0 && floorAndProperties.Handle != null) // Only when at least the body rep exists will come here { - IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations); + prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations); + } + + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(prodRep)) + { prodReps.Add(prodRep); } if (floorAndProperties.Data != null) + { loopExtraParams.Add(floorAndProperties.Data); + } } } } @@ -410,7 +416,7 @@ class FloorExporter canExportAsInternalExtrusion = openingDataList == null || openingDataList.Count == 0; } - if (canExportAsInternalExtrusion && ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4x3) + if (canExportAsInternalExtrusion) { loopExtraParams.Clear(); IList extrusionParams = new List(); @@ -464,7 +470,10 @@ class FloorExporter if (exportByComponents) { prodDefHnd = RepresentationUtil.CreateProductDefinitionShapeWithoutBodyRep(exporterIFC, floorElement, catId, geometryElement, null); - prodReps.Add(prodDefHnd); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(prodDefHnd)) + { + prodReps.Add(prodDefHnd); + } } else { @@ -494,7 +503,7 @@ class FloorExporter switch (exportType.ExportInstance) { case IFCEntityType.IfcCovering: - exportType.ValidatedPredefinedType = IFCValidateEntry.GetValidIFCType(floorElement, ifcEnumType, "FLOORING"); + exportType.PredefinedType = IFCValidateEntry.GetValidIFCType(floorElement, ifcEnumType, "FLOORING"); break; case IFCEntityType.IfcSlab: { @@ -515,7 +524,7 @@ class FloorExporter } } - exportType.ValidatedPredefinedType = IFCValidateEntry.GetValidIFCType(floorElement, ifcEnumType, isBaseSlab ? "BASESLAB" : "FLOOR"); + exportType.PredefinedType = IFCValidateEntry.GetValidIFCType(floorElement, ifcEnumType, isBaseSlab ? "BASESLAB" : "FLOOR"); } break; } @@ -577,7 +586,7 @@ class FloorExporter for (int ii = 0; ii < numReps; ii++) { - IFCExportBodyParams loopExtraParam = ii < loopExtraParams.Count ? loopExtraParams[ii] : null; + IFCExportBodyParams loopExtraParam = ii < loopExtraParams.Count ? loopExtraParams[ii] : ecData; productWrapper.AddElement(floorElement, slabHnds[ii], placementSetter, loopExtraParam, true, exportType); ExporterCacheManager.TypeRelationsCache.Add(typeHandle, slabHnds[ii]); diff --git a/Source/Revit.IFC.Export/Exporter/GenericElementExporter.cs b/Source/Revit.IFC.Export/Exporter/GenericElementExporter.cs index 5b9be076..08e3fb55 100644 --- a/Source/Revit.IFC.Export/Exporter/GenericElementExporter.cs +++ b/Source/Revit.IFC.Export/Exporter/GenericElementExporter.cs @@ -32,7 +32,7 @@ class GenericElementExporter // Check the intended IFC entity or type name is in the exclude list specified in the UI if (exportType.ExportInstance == IFCEntityType.UnKnown) - exportType.SetValueWithPair(IFCEntityType.IfcBuildingElementProxy, exportType.ValidatedPredefinedType); + exportType.SetByTypeAndPredefinedType(IFCEntityType.IfcBuildingElementProxy, exportType.PredefinedType); if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(exportType.ExportInstance)) return null; @@ -78,11 +78,8 @@ class GenericElementExporter HashSet propertySetsOpt = new HashSet(); IList repMapListOpt = new List(); - string typeGuid = FamilyExporterUtil.GetGUIDForFamilySymbol(element as FamilyInstance, - familySymbol, exportType); - styleHandle = FamilyExporterUtil.ExportGenericType(exporterIFC, exportType, - exportType.ValidatedPredefinedType, propertySetsOpt, repMapListOpt, - element, familySymbol, typeGuid); + string typeGuid = FamilyExporterUtil.GetGUIDForFamilySymbol(element as FamilyInstance, familySymbol, exportType); + styleHandle = FamilyExporterUtil.ExportGenericType(exporterIFC, exportType, propertySetsOpt, repMapListOpt, element, familySymbol, typeGuid); productWrapper.RegisterHandleWithElementType(familySymbol, exportType, styleHandle, propertySetsOpt); } @@ -219,7 +216,7 @@ private static GeometryInstance GetTheGeometryInstance(GeometryElement geomElem) extraParams.GetLocalPlacement()); IFCAnyHandle typeStyle = FamilyInstanceExporter.CreateTypeEntityHandle(exporterIFC, - typeKey, ref typeInfo, null, representations3D, repMapTrfList, null, + typeKey, ref typeInfo, null, representations3D, repMapTrfList, null, null, element, elementType, elementType, ElementId.InvalidElementId, false, false, exportType, out HashSet propertySets); @@ -283,7 +280,7 @@ private static GeometryInstance GetTheGeometryInstance(GeometryElement geomElem) { string instanceGUID = GUIDUtil.CreateGUID(element); - bool isChildInContainer = element.AssemblyInstanceId != ElementId.InvalidElementId; + bool isChildInContainer = ExporterUtil.IsContainedInAssembly(element); if (IFCAnyHandleUtil.IsNullOrHasNoValue(instanceHandle)) { @@ -304,7 +301,7 @@ private static GeometryInstance GetTheGeometryInstance(GeometryElement geomElem) else { instanceHandle = IFCInstanceExporter.CreateBuildingElementProxy(exporterIFC, element, instanceGUID, - ownerHistory, localPlacementToUse, repHnd, exportType.ValidatedPredefinedType); + ownerHistory, localPlacementToUse, repHnd, exportType.GetPredefinedTypeOrDefault()); } bool associateToLevel = !containedInSpace && !isChildInContainer; @@ -358,8 +355,7 @@ private static GeometryInstance GetTheGeometryInstance(GeometryElement geomElem) public static bool ExportElement(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, ProductWrapper productWrapper) { - string ifcEnumType; - IFCExportInfoPair exportType = ExporterUtil.GetProductExportType(exporterIFC, element, out ifcEnumType); + IFCExportInfoPair exportType = ExporterUtil.GetProductExportType(exporterIFC, element, out _); // Check the intended IFC entity or type name is in the exclude list specified in the UI IFCEntityType elementClassTypeEnum; @@ -373,7 +369,7 @@ private static GeometryInstance GetTheGeometryInstance(GeometryElement geomElem) return true; if (FamilyInstanceExporter.ExportGenericToSpecificElement(exporterIFC, - element, ref geometryElement, exportType, ifcEnumType, productWrapper)) + element, ref geometryElement, exportType, productWrapper)) return true; return (ExportSimpleGenericElement(exporterIFC, element, geometryElement, productWrapper, diff --git a/Source/Revit.IFC.Export/Exporter/GenericMEPExporter.cs b/Source/Revit.IFC.Export/Exporter/GenericMEPExporter.cs index 37588788..d01dd68c 100644 --- a/Source/Revit.IFC.Export/Exporter/GenericMEPExporter.cs +++ b/Source/Revit.IFC.Export/Exporter/GenericMEPExporter.cs @@ -59,7 +59,7 @@ class GenericMEPExporter // associated with the assembly, on the level of the assembly. if ((exportType.ExportType == IFCEntityType.IfcDuctSegmentType) && (ExporterCacheManager.ExportOptionsCache.WallAndColumnSplitting) && - (element.AssemblyInstanceId == ElementId.InvalidElementId)) + !ExporterUtil.IsContainedInAssembly(element)) { LevelUtil.CreateSplitLevelRangesForElement(exporterIFC, exportType, element, out levels, out ranges); @@ -207,8 +207,7 @@ class GenericMEPExporter IList repMapListOpt = new List(); string typeGuid = FamilyExporterUtil.GetGUIDForFamilySymbol(element as FamilyInstance, type, exportType); - styleHandle = FamilyExporterUtil.ExportGenericType(exporterIFC, exportType, ifcEnumType, - propertySetsOpt, repMapListOpt, element, type, typeGuid); + styleHandle = FamilyExporterUtil.ExportGenericType(exporterIFC, exportType, propertySetsOpt, repMapListOpt, element, type, typeGuid); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(styleHandle)) { productWrapper.RegisterHandleWithElementType(type, exportType, styleHandle, null); diff --git a/Source/Revit.IFC.Export/Exporter/GridExporter.cs b/Source/Revit.IFC.Export/Exporter/GridExporter.cs index e1840e0b..8fe6a0ee 100644 --- a/Source/Revit.IFC.Export/Exporter/GridExporter.cs +++ b/Source/Revit.IFC.Export/Exporter/GridExporter.cs @@ -440,15 +440,18 @@ public class GridRepresentationData if (currentLevel != null) { - levelIds.Add(currentLevel.Elevation, currentLevel.Id); + levelIds.Add(currentLevel.ProjectElevation, currentLevel.Id); } else { foreach (ElementId levelId in ExporterCacheManager.LevelInfoCache.BuildingStoriesByElevation) { Level level = document.GetElement(levelId) as Level; - if (!levelIds.ContainsKey(level.Elevation)) - levelIds.Add(level.Elevation, levelId); + double? projectElevation = level?.ProjectElevation; + if (projectElevation.HasValue && !levelIds.ContainsKey(projectElevation.Value)) + { + levelIds.Add(projectElevation.Value, levelId); + } } } diff --git a/Source/Revit.IFC.Export/Exporter/HostObjectExporter.cs b/Source/Revit.IFC.Export/Exporter/HostObjectExporter.cs index 7befce3d..0a865d5e 100644 --- a/Source/Revit.IFC.Export/Exporter/HostObjectExporter.cs +++ b/Source/Revit.IFC.Export/Exporter/HostObjectExporter.cs @@ -46,15 +46,13 @@ class HostObjectExporter /// The level id. /// The IFCLayerSetDirection. /// True if the geometry contains BRep geoemtry. If so, we will export an IfcMaterialList + /// Material layer info. /// True if exported successfully, false otherwise. public static bool ExportHostObjectMaterials(ExporterIFC exporterIFC, HostObject hostObject, IList elemHnds, GeometryElement geometryElement, ProductWrapper productWrapper, - ElementId levelId, Toolkit.IFCLayerSetDirection direction, bool containsBRepGeometry, IFCAnyHandle typeHnd = null) + ElementId levelId, IFCLayerSetDirection direction, bool containsBRepGeometry, IFCAnyHandle typeHnd = null, MaterialLayerSetInfo layersetInfo = null) { - if (hostObject == null) - return true; //nothing to do - - if (elemHnds == null || (elemHnds.Count == 0)) + if (hostObject == null || ((elemHnds?.Count ?? 0) == 0)) return true; //nothing to do IFCFile file = exporterIFC.GetFile(); @@ -72,9 +70,9 @@ class HostObjectExporter wallHeight = boundingBox.Max.Z - boundingBox.Min.Z; } - MaterialLayerSetInfo mlsInfo = new MaterialLayerSetInfo(exporterIFC, hostObject, productWrapper, geometryElement); + MaterialLayerSetInfo mlsInfo = layersetInfo == null ? new MaterialLayerSetInfo(exporterIFC, hostObject, productWrapper, geometryElement) : layersetInfo; IFCAnyHandle materialLayerSet = mlsInfo.MaterialLayerSetHandle; - List materialIds = mlsInfo.MaterialIds.Select(x => x.m_baseMatId).ToList(); + List materialIds = mlsInfo.MaterialIds.Select(x => x.BaseMatId).ToList(); // Among all the calls of this method the problem of material association absence was found only // for CeilingAndFloor host object type (see JIRA item REVIT-164913) @@ -181,7 +179,8 @@ class HostObjectExporter double offsetFromReferenceLine = flipDirSense ? -scaledOffset : scaledOffset; IFCDirectionSense sense = flipDirSense ? IFCDirectionSense.Negative : IFCDirectionSense.Positive; - layerSetUsage = CategoryUtil.CreateMaterialLayerSetUsage(file, materialLayerSet, direction, sense, offsetFromReferenceLine); + layerSetUsage = IFCInstanceExporter.CreateMaterialLayerSetUsage(file, materialLayerSet, + direction, sense, offsetFromReferenceLine); } ExporterCacheManager.MaterialSetUsageCache.Add(layerSetUsage, elemHnd); } @@ -243,18 +242,22 @@ class HostObjectExporter /// The level id. /// The IFCLayerSetDirection. /// True if the geometry contains BRep geoemtry. If so, we will export an IfcMaterialList. If null, we will calculate. + /// Material layer info. /// True if exported successfully, false otherwise. public static bool ExportHostObjectMaterials(ExporterIFC exporterIFC, HostObject hostObject, IFCAnyHandle elemHnd, GeometryElement geometryElement, ProductWrapper productWrapper, - ElementId levelId, Toolkit.IFCLayerSetDirection direction, bool? containsBRepGeometry, IFCAnyHandle typeHnd) + ElementId levelId, IFCLayerSetDirection direction, bool? containsBRepGeometry, IFCAnyHandle typeHnd, MaterialLayerSetInfo layersetInfo = null) { - IList elemHnds = new List(); - elemHnds.Add(elemHnd); + if (IFCAnyHandleUtil.IsNullOrHasNoValue(elemHnd)) + return false; + + IList elemHnds = new List() { elemHnd }; // Setting doesContainBRepGeometry to false below preserves the original behavior that we created IfcMaterialLists for all geometries. // TODO: calculate, or pass in, a valid bool value for Ceilings, Roofs, and Wall Sweeps. bool doesContainBRepGeometry = containsBRepGeometry.HasValue ? containsBRepGeometry.Value : false; - return ExportHostObjectMaterials(exporterIFC, hostObject, elemHnds, geometryElement, productWrapper, levelId, direction, doesContainBRepGeometry, typeHnd); + return ExportHostObjectMaterials(exporterIFC, hostObject, elemHnds, geometryElement, productWrapper, levelId, + direction, doesContainBRepGeometry, typeHnd, layersetInfo); } /// diff --git a/Source/Revit.IFC.Export/Exporter/HostedSweepExporter.cs b/Source/Revit.IFC.Export/Exporter/HostedSweepExporter.cs index 5aed8a29..5e82b6d0 100644 --- a/Source/Revit.IFC.Export/Exporter/HostedSweepExporter.cs +++ b/Source/Revit.IFC.Export/Exporter/HostedSweepExporter.cs @@ -18,13 +18,9 @@ // using System; -using System.Collections.Generic; using Autodesk.Revit.DB; using Autodesk.Revit.DB.IFC; using Revit.IFC.Export.Utility; -using Revit.IFC.Export.Toolkit; -using Revit.IFC.Common.Utility; -using Revit.IFC.Common.Enums; namespace Revit.IFC.Export.Exporter { @@ -42,115 +38,7 @@ class HostedSweepExporter /// The ProductWrapper. public static void Export(ExporterIFC exporterIFC, HostedSweep hostedSweep, GeometryElement geometryElement, ProductWrapper productWrapper) { - ElementId catId = CategoryUtil.GetSafeCategoryId(hostedSweep); - if (catId == new ElementId(BuiltInCategory.OST_Gutter)) - ExportGutter(exporterIFC, hostedSweep, geometryElement, productWrapper); - else - GenericElementExporter.ExportElement(exporterIFC, hostedSweep, geometryElement, productWrapper); - } - - /// - /// Exports a gutter element. - /// - /// The ExporterIFC object. - /// The element. - /// The geometry element. - /// The ProductWrapper. - public static void ExportGutter(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, ProductWrapper productWrapper) - { - // Check the intended IFC entity or type name is in the exclude list specified in the UI - Common.Enums.IFCEntityType elementClassTypeEnum = Common.Enums.IFCEntityType.IfcPipeSegmentType; - if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) - return; - - IFCFile file = exporterIFC.GetFile(); - - using (IFCTransaction tr = new IFCTransaction(file)) - { - // Check for containment override - IFCAnyHandle overrideContainerHnd = null; - ElementId overrideContainerId = ParameterUtil.OverrideContainmentParameter(exporterIFC, element, out overrideContainerHnd); - - using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element, null, null, overrideContainerId, overrideContainerHnd)) - { - using (IFCExportBodyParams ecData = new IFCExportBodyParams()) - { - ecData.SetLocalPlacement(setter.LocalPlacement); - - ElementId categoryId = CategoryUtil.GetSafeCategoryId(element); - - BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow); - IFCAnyHandle bodyRep = BodyExporter.ExportBody(exporterIFC, element, categoryId, ElementId.InvalidElementId, - geometryElement, bodyExporterOptions, ecData).RepresentationHnd; - if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep)) - { - if (ecData != null) - ecData.ClearOpenings(); - return; - } - string originalTag = NamingUtil.CreateIFCElementId(element); - - // In Revit, we don't have a corresponding type, so we create one for every gutter. - IFCAnyHandle origin = ExporterUtil.CreateAxis2Placement3D(file); - IFCAnyHandle repMap3dHnd = IFCInstanceExporter.CreateRepresentationMap(file, origin, bodyRep); - List repMapList = new List(); - repMapList.Add(repMap3dHnd); - string elementTypeName = NamingUtil.CreateIFCObjectName(exporterIFC, element); - - string typeGuid = GUIDUtil.CreateSubElementGUID(element, (int)IFCHostedSweepSubElements.PipeSegmentType); - IFCAnyHandle style = IFCInstanceExporter.CreatePipeSegmentType(file, null, typeGuid, - null, repMapList, IFCPipeSegmentType.Gutter); - IFCAnyHandleUtil.OverrideNameAttribute(style, elementTypeName); - IFCExportInfoPair exportInfo = new IFCExportInfoPair(IFCEntityType.IfcPipeSegmentType, IFCPipeSegmentType.Gutter.ToString()); - - IFCAnyHandleUtil.SetAttribute(style, "Tag", originalTag); - IFCAnyHandleUtil.SetAttribute(style, "ElementType", elementTypeName); - - List representationMaps = GeometryUtil.GetRepresentationMaps(style); - IFCAnyHandle mappedItem = ExporterUtil.CreateDefaultMappedItem(file, representationMaps[0]); - - ISet representations = new HashSet(); - representations.Add(mappedItem); - - IFCAnyHandle bodyMappedItemRep = RepresentationUtil.CreateBodyMappedItemRep(exporterIFC, - element, categoryId, exporterIFC.Get3DContextHandle("Body"), representations); - if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyMappedItemRep)) - return; - - List shapeReps = new List(); - shapeReps.Add(bodyMappedItemRep); - - IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geometryElement, Transform.Identity); - if (boundingBoxRep != null) - shapeReps.Add(boundingBoxRep); - - IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps); - IFCAnyHandle localPlacementToUse; - ElementId roomId = setter.UpdateRoomRelativeCoordinates(element, out localPlacementToUse); - if (roomId == ElementId.InvalidElementId) - localPlacementToUse = ecData.GetLocalPlacement(); - - string guid = GUIDUtil.CreateGUID(element); - - IFCAnyHandle elemHnd = IFCInstanceExporter.CreateFlowSegment(exporterIFC, element, guid, - ExporterCacheManager.OwnerHistoryHandle, localPlacementToUse, prodRep); - - bool containedInSpace = (roomId != ElementId.InvalidElementId); - productWrapper.AddElement(element, elemHnd, setter.LevelInfo, ecData, !containedInSpace, exportInfo); - - if (containedInSpace) - ExporterCacheManager.SpaceInfoCache.RelateToSpace(roomId, elemHnd); - - // Associate segment with type. - ExporterCacheManager.TypeRelationsCache.Add(style, elemHnd); - - OpeningUtil.CreateOpeningsIfNecessary(elemHnd, element, ecData, null, - exporterIFC, localPlacementToUse, setter, productWrapper); - } - - tr.Commit(); - } - } + GenericElementExporter.ExportElement(exporterIFC, hostedSweep, geometryElement, productWrapper); } } } \ No newline at end of file diff --git a/Source/Revit.IFC.Export/Exporter/IFCEntityAndPsetList.cs b/Source/Revit.IFC.Export/Exporter/IFCEntityAndPsetList.cs index 082c613a..c4f4d8e2 100644 --- a/Source/Revit.IFC.Export/Exporter/IFCEntityAndPsetList.cs +++ b/Source/Revit.IFC.Export/Exporter/IFCEntityAndPsetList.cs @@ -4,9 +4,9 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -using System.Web.Script.Serialization; using System.Runtime.Serialization; using System.Xml; +using Newtonsoft.Json; namespace Revit.IFC.Export.Utility { @@ -103,10 +103,7 @@ public IFCCertifiedEntitiesAndPSets() if (File.Exists(filePath)) { - // JavaScriptSerializer does not support mapping of Json array into Hashset (it expects List) and this code below gets the data into Lists first - // and then transfers the data to the final form using Hashset for performance reason - JavaScriptSerializer jsonConvert = new JavaScriptSerializer(); - IDictionary CertifiedEntityAndPsetList = jsonConvert.Deserialize>(File.ReadAllText(filePath)); + IDictionary CertifiedEntityAndPsetList = JsonConvert.DeserializeObject>(File.ReadAllText(filePath)); // Copy the data to the desired format using Hashset in IFCEntityAndPsetList foreach (KeyValuePair entPsetData in CertifiedEntityAndPsetList) { diff --git a/Source/Revit.IFC.Export/Exporter/PartExporter.cs b/Source/Revit.IFC.Export/Exporter/PartExporter.cs index d1c093ef..18ade433 100644 --- a/Source/Revit.IFC.Export/Exporter/PartExporter.cs +++ b/Source/Revit.IFC.Export/Exporter/PartExporter.cs @@ -293,8 +293,7 @@ public static void ExportPartAsBuildingElement(ExporterIFC exporterIFC, Element case PartExportMode.AsBuildingElement: case PartExportMode.ShapeRepresentationOnly: { - string ifcEnumType = null; - IFCExportInfoPair exportType = ExporterUtil.GetProductExportType(exporterIFC, hostElement, out ifcEnumType); + IFCExportInfoPair exportType = ExporterUtil.GetProductExportType(exporterIFC, hostElement, out _); // Check the intended IFC entity or type name is in the exclude list specified in the UI IFCEntityType elementClassTypeEnum; @@ -371,7 +370,8 @@ public static void ExportPartAsBuildingElement(ExporterIFC exporterIFC, Element } hostTrf = ExporterUtil.GetTransformFromLocalPlacementHnd(originalPlacement); hostTrf = ExporterUtil.UnscaleTransformOrigin(hostTrf); - geometryElement = GeometryUtil.GetTransformedGeometry(geometryElement, hostTrf.Inverse); + geometryElement = SolidMeshGeometryInfo.GetTransformedGeometry(geometryElement, hostTrf.Inverse, + ExporterCacheManager.AllocatedGeometryObjectCache); } // The host placement setter has registered the transform. Since the part geometry is transformed relative to the host, // the placement for the part needs to be inversed @@ -445,8 +445,8 @@ public static void ExportPartAsBuildingElement(ExporterIFC exporterIFC, Element IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; - string ifcEnumType = null; - IFCExportInfoPair exportType = ExporterUtil.GetProductExportType(exporterIFC, (hostElement != null) ? hostElement : partElement, out ifcEnumType); + IFCExportInfoPair exportType = ExporterUtil.GetProductExportType(exporterIFC, (hostElement != null) ? hostElement : partElement, out _); + string ifcEnumType = exportType.GetPredefinedTypeOrDefault(); string partGUID = GUIDUtil.GenerateIFCGuidFrom(partElement, exportType); IFCAnyHandle ifcPart = null; if (exportMode != PartExportMode.AsBuildingElement) @@ -499,12 +499,12 @@ public static void ExportPartAsBuildingElement(ExporterIFC exporterIFC, Element break; default: ifcPart = IFCInstanceExporter.CreateBuildingElementProxy(exporterIFC, partElement, partGUID, ownerHistory, - extrusionCreationData.GetLocalPlacement(), prodRep, exportType.ValidatedPredefinedType); + extrusionCreationData.GetLocalPlacement(), prodRep, ifcEnumType); break; } } - if (setMaterialNameToPartName) + if (setMaterialNameToPartName && (bodyData?.MaterialIds?.Count ?? 0) > 0) { Material material = partElement.Document.GetElement(bodyData.MaterialIds[0]) as Material; if (material != null) @@ -693,10 +693,12 @@ public static void ExportPartAsBuildingElement(ExporterIFC exporterIFC, Element // material. It is not very correct, but it will produce consistent output var matList = (from x in layersetInfo.MaterialIds - where !MathUtil.IsAlmostZero(x.m_matWidth) - select new MaterialLayerSetInfo.MaterialInfo(x.m_baseMatId, x.m_layerName, x.m_matWidth, x.m_function)).ToList(); - if (matList != null && matList.Count > 0) + where !MathUtil.IsAlmostZero(x.Width) + select new MaterialLayerSetInfo.MaterialInfo(x.BaseMatId, x.LayerName, x.Width, x.Function)).ToList(); + if ((matList?.Count ?? 0) > 0) + { layersetInfoList.Add(matList[0]); // add only the first non-zero thickness + } } else { @@ -716,7 +718,7 @@ public static void ExportPartAsBuildingElement(ExporterIFC exporterIFC, Element } else { - IList matInfoList = layersetInfo.MaterialIds.Where(x => !MathUtil.IsAlmostZero(x.m_matWidth)).Select(x => x.m_baseMatId).ToList(); + IList matInfoList = layersetInfo.MaterialIds.Where(x => !MathUtil.IsAlmostZero(x.Width)).Select(x => x.BaseMatId).ToList(); // There is a chance that the material list is already correct or just in reverse order, so handle it before moving on to manual sequencing MaterialLayerSetInfo.CompareTwoLists compStat = MaterialLayerSetInfo.CompareMaterialInfoList(bodyData.MaterialIds, matInfoList); switch (compStat) @@ -738,7 +740,7 @@ public static void ExportPartAsBuildingElement(ExporterIFC exporterIFC, Element layersetInfoList = CollectMaterialInfoList(hostElement, associatedPartsList, layersetInfo); // There is a chance that the manually collected list will be reversed or incorrect, so check it again - IList newMatInfoList = layersetInfoList.Where(x => !MathUtil.IsAlmostZero(x.m_matWidth)).Select(x => x.m_baseMatId).ToList(); + IList newMatInfoList = layersetInfoList.Where(x => !MathUtil.IsAlmostZero(x.Width)).Select(x => x.BaseMatId).ToList(); compStat = MaterialLayerSetInfo.CompareMaterialInfoList(newMatInfoList, matInfoList); if (compStat == MaterialLayerSetInfo.CompareTwoLists.ListsReversedEqual) layersetInfoList = layersetInfoList.Reverse().ToList(); @@ -752,14 +754,24 @@ public static void ExportPartAsBuildingElement(ExporterIFC exporterIFC, Element { // We still cannot match the layer, it could be no layer. Use only the first material MaterialLayerSetInfo.MaterialInfo layer1 = layersetInfo.MaterialIds[0]; - layersetInfo.SingleMaterialOverride(layer1.m_baseMatId, layer1.m_matWidth); + layersetInfo.SingleMaterialOverride(layer1.BaseMatId, layer1.Width); layersetInfoList.Add(layer1); } } } // Scan through the prodReps and remove any existing "Body" rep if it is already in there, if there is, it will be removed and replaced with the parts - List prodReps = IFCAnyHandleUtil.GetRepresentations(hostProdDefShape); + List prodReps; + if (hostProdDefShape == null) + { + hostProdDefShape = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, null); + prodReps = new List(); + } + else + { + prodReps = IFCAnyHandleUtil.GetRepresentations(hostProdDefShape); + } + int repToRemove = -1; for (int rCnt = 0; rCnt < prodReps.Count; ++rCnt) { @@ -781,7 +793,7 @@ public static void ExportPartAsBuildingElement(ExporterIFC exporterIFC, Element int layerSetInfoCount = layersetInfoList.Count; int cnt = 0; - var layerInfoInxs = new List<(int idx, IFCAnyHandle rep)>(itemReps.Count); + var layerInfoInxs = new List<(int Index, IFCAnyHandle Representation)>(itemReps.Count); foreach (IFCAnyHandle itemRep in itemReps) { int layerInfoIdx = -1; @@ -800,19 +812,26 @@ public static void ExportPartAsBuildingElement(ExporterIFC exporterIFC, Element cnt++; } - layerInfoInxs = layerInfoInxs.OrderBy(x => x.idx).ToList(); + layerInfoInxs = layerInfoInxs.OrderBy(x => x.Index).ToList(); - var uniqueNames = new Dictionary<(string, double), string>(new MaterialLayerSetInfo.NameAndWidthComparer()); + HashSet shapeAspectNameUsed = new HashSet(); foreach (var layerInfo in layerInfoInxs) { - string layerName = (layerInfo.idx != -1) ? layersetInfoList[layerInfo.idx].m_layerName : "Layer"; - double layerWidth = (layerInfo.idx != -1) ? layersetInfoList[layerInfo.idx].m_matWidth : 0.0; + int layerIndex = layerInfo.Index; - if (string.IsNullOrEmpty(layerName)) - layerName = "Layer"; + string shapeAspectName = (layerIndex != -1) ? layersetInfoList[layerIndex].ShapeAspectName : "Layer"; + if (string.IsNullOrEmpty(shapeAspectName)) + shapeAspectName = "Layer"; + + // Ensure IfcShapeAspect name is unique and save it for consistensy to IfcMaterialConstituent. + shapeAspectName = NamingUtil.GetUniqueNameWithinSet(shapeAspectName, shapeAspectNameUsed); + if (layerIndex >= 0 && layerIndex < layerSetInfoCount) + { + layersetInfoList[layerIndex].ShapeAspectName = shapeAspectName; + } - string uniqueName = MaterialLayerSetInfo.GetUniqueMaterialNameWithWidth(layerName, layerWidth, uniqueNames); - RepresentationUtil.CreateRepForShapeAspect(exporterIFC, hostElement, hostProdDefShape, representationType, uniqueName, layerInfo.rep); + RepresentationUtil.CreateRepForShapeAspect(exporterIFC, hostElement, hostProdDefShape, representationType, + shapeAspectName, layerInfo.Representation); } return hostShapeRep; @@ -940,7 +959,7 @@ private static IList CollectMaterialInfoList( foreach (MaterialLayerSetInfo.MaterialInfo layerInfo in layersetInfo.MaterialIds) { // Face's material ID == layer's material ID && face's width == layer's width - if (faceInfo.Value.Item2.MaterialElementId == layerInfo.m_baseMatId && MathUtil.IsAlmostEqual(faceInfo.Value.Item1, layerInfo.m_matWidth)) + if (faceInfo.Value.Item2.MaterialElementId == layerInfo.BaseMatId && MathUtil.IsAlmostEqual(faceInfo.Value.Item1, layerInfo.Width)) { layersetInfoList.Add(layerInfo); break; @@ -990,7 +1009,7 @@ public static bool ShouldExportParts(Element hostElement, int layersCount) layersCount > 1)); } /// - /// Checks if elemnt has associated parts and all conditions are met for exporting it as Parts. + /// Checks if element has associated parts and all conditions are met for exporting it as Parts. /// /// The host element. /// True if host element can export the parts, false otherwise. @@ -1118,6 +1137,7 @@ private static IFCExtrusionAxes GetDefaultExtrusionAxesForHost(ExporterIFC expor case IFCEntityType.IfcCovering: case IFCEntityType.IfcSlab: case IFCEntityType.IfcRoof: + case IFCEntityType.IfcBuildingElementProxy: return IFCExtrusionAxes.TryZ; default: return IFCExtrusionAxes.TryXY; diff --git a/Source/Revit.IFC.Export/Exporter/PropertySet/Calculators/GrossAreaCalculator.cs b/Source/Revit.IFC.Export/Exporter/PropertySet/Calculators/GrossAreaCalculator.cs index ce8bc42d..3683445e 100644 --- a/Source/Revit.IFC.Export/Exporter/PropertySet/Calculators/GrossAreaCalculator.cs +++ b/Source/Revit.IFC.Export/Exporter/PropertySet/Calculators/GrossAreaCalculator.cs @@ -76,13 +76,20 @@ public override bool Calculate(ExporterIFC exporterIFC, IFCExportBodyParams extr if (m_Area > MathUtil.Eps() * MathUtil.Eps()) return true; - if (extrusionCreationData == null) - return false; + if (extrusionCreationData != null) + { + m_Area = extrusionCreationData.ScaledArea; - m_Area = extrusionCreationData.ScaledArea; + if (m_Area > MathUtil.Eps() * MathUtil.Eps()) + return true; + } - if (m_Area > MathUtil.Eps() * MathUtil.Eps()) - return true; + if (ParameterUtil.GetDoubleValueFromElementOrSymbol(element, BuiltInParameter.HOST_AREA_COMPUTED, out m_Area) != null) + { + m_Area = UnitUtil.ScaleArea(m_Area); + if (m_Area > MathUtil.Eps() * MathUtil.Eps()) + return true; + } return false; } diff --git a/Source/Revit.IFC.Export/Exporter/PropertySet/Calculators/GrossCeilingAreaCalculator.cs b/Source/Revit.IFC.Export/Exporter/PropertySet/Calculators/GrossCeilingAreaCalculator.cs index b7c8ba7d..7f9f7983 100644 --- a/Source/Revit.IFC.Export/Exporter/PropertySet/Calculators/GrossCeilingAreaCalculator.cs +++ b/Source/Revit.IFC.Export/Exporter/PropertySet/Calculators/GrossCeilingAreaCalculator.cs @@ -76,6 +76,10 @@ public override bool Calculate(ExporterIFC exporterIFC, IFCExportBodyParams extr if (m_Area > MathUtil.Eps() * MathUtil.Eps()) return true; + m_Area = UnitUtil.ScaleArea(CalculateSpatialElementGrossCeilingArea(element as SpatialElement)); + if (m_Area > MathUtil.Eps() * MathUtil.Eps()) + return true; + if (ParameterUtil.GetDoubleValueFromElementOrSymbol(element, BuiltInParameter.HOST_AREA_COMPUTED, out m_Area) != null) { m_Area = UnitUtil.ScaleArea(m_Area); @@ -94,6 +98,45 @@ public override bool Calculate(ExporterIFC exporterIFC, IFCExportBodyParams extr return false; } + private double CalculateSpatialElementGrossCeilingArea(SpatialElement spatialElement) + { + double area = 0.0; + + if (spatialElement == null) + return area; + + // Get the outer boundary loops of the SpatialElement. + IList> boundaryLoops = spatialElement.GetBoundarySegments(new SpatialElementBoundaryOptions()); + + //Search for a outer loop with the largest area. + foreach (IList boundaryLoop in boundaryLoops) + { + CurveLoop curveLoop = new CurveLoop(); + foreach (BoundarySegment boundarySegment in boundaryLoop) + { + try + { + Curve curve = boundarySegment.GetCurve(); + curveLoop.Append(curve); + } + catch (Autodesk.Revit.Exceptions.ArgumentException) + { + //For some special cases, BoundarySegments of the element are not valid for CurveLoop creation + //(curveLoop.Append(curve) throws exception because "This curve will make the loop discontinuous.") + + return 0.0; + } + } + + double loopArea = ExporterIFCUtils.ComputeAreaOfCurveLoops(new List() { curveLoop }); + + if (area < loopArea) + area = loopArea; + } + + return area; + } + /// /// Gets the calculated double value. /// diff --git a/Source/Revit.IFC.Export/Exporter/PropertySet/Calculators/GrossFloorAreaCalculator.cs b/Source/Revit.IFC.Export/Exporter/PropertySet/Calculators/GrossFloorAreaCalculator.cs index d198a5b4..780498d6 100644 --- a/Source/Revit.IFC.Export/Exporter/PropertySet/Calculators/GrossFloorAreaCalculator.cs +++ b/Source/Revit.IFC.Export/Exporter/PropertySet/Calculators/GrossFloorAreaCalculator.cs @@ -76,6 +76,10 @@ public override bool Calculate(ExporterIFC exporterIFC, IFCExportBodyParams extr if (m_Area > MathUtil.Eps() * MathUtil.Eps()) return true; + m_Area = UnitUtil.ScaleArea(CalculateSpatialElementGrossFloorArea(element as SpatialElement)); + if (m_Area > MathUtil.Eps() * MathUtil.Eps()) + return true; + if (extrusionCreationData == null) return false; @@ -87,6 +91,45 @@ public override bool Calculate(ExporterIFC exporterIFC, IFCExportBodyParams extr return false; } + private double CalculateSpatialElementGrossFloorArea(SpatialElement spatialElement) + { + double area = 0.0; + + if (spatialElement == null) + return area; + + // Get the outer boundary loops of the SpatialElement. + IList> boundaryLoops = spatialElement.GetBoundarySegments(new SpatialElementBoundaryOptions()); + + //Search for a outer loop with the largest area. + foreach (IList boundaryLoop in boundaryLoops) + { + CurveLoop curveLoop = new CurveLoop(); + foreach (BoundarySegment boundarySegment in boundaryLoop) + { + try + { + Curve curve = boundarySegment.GetCurve(); + curveLoop.Append(curve); + } + catch (Autodesk.Revit.Exceptions.ArgumentException) + { + //For some special cases, BoundarySegments of the element are not valid for CurveLoop creation + //(curveLoop.Append(curve) throws exception because "This curve will make the loop discontinuous.") + + return 0.0; + } + } + + double loopArea = ExporterIFCUtils.ComputeAreaOfCurveLoops(new List() { curveLoop }); + + if (area < loopArea) + area = loopArea; + } + + return area; + } + /// /// Gets the calculated double value. /// diff --git a/Source/Revit.IFC.Export/Exporter/PropertySet/Calculators/GrossVolumeCalculator.cs b/Source/Revit.IFC.Export/Exporter/PropertySet/Calculators/GrossVolumeCalculator.cs index 08977bc8..bb90be15 100644 --- a/Source/Revit.IFC.Export/Exporter/PropertySet/Calculators/GrossVolumeCalculator.cs +++ b/Source/Revit.IFC.Export/Exporter/PropertySet/Calculators/GrossVolumeCalculator.cs @@ -17,6 +17,7 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // +using System.Collections.Generic; using Autodesk.Revit.DB; using Autodesk.Revit.DB.IFC; using Revit.IFC.Export.Utility; @@ -38,7 +39,7 @@ class GrossVolumeCalculator : PropertyCalculator /// The SlabGrossVolumeCalculator instance. /// public static GrossVolumeCalculator Instance { get; } = new GrossVolumeCalculator(); - + /// /// Calculates gross volume. /// @@ -56,6 +57,10 @@ public override bool Calculate(ExporterIFC exporterIFC, IFCExportBodyParams extr return true; } + m_Volume = UnitUtil.ScaleVolume(CalculateSpatialElementGrossVolume(element as SpatialElement, extrusionCreationData)); + if (m_Volume > MathUtil.Eps() * MathUtil.Eps() * MathUtil.Eps()) + return true; + if (extrusionCreationData == null) return false; @@ -68,6 +73,47 @@ public override bool Calculate(ExporterIFC exporterIFC, IFCExportBodyParams extr return (m_Volume > MathUtil.Eps() * MathUtil.Eps() * MathUtil.Eps()); } + private double CalculateSpatialElementGrossVolume(SpatialElement spatialElement, IFCExportBodyParams extrusionCreationData) + { + double area = 0.0; + + if (spatialElement == null || extrusionCreationData == null) + return area; + + // Get the outer boundary loops of the SpatialElement. + IList> boundaryLoops = spatialElement.GetBoundarySegments(new SpatialElementBoundaryOptions()); + + //Search for a outer loop with the largest area. + foreach (IList boundaryLoop in boundaryLoops) + { + CurveLoop curveLoop = new CurveLoop(); + foreach (BoundarySegment boundarySegment in boundaryLoop) + { + try + { + Curve curve = boundarySegment.GetCurve(); + curveLoop.Append(curve); + } + catch (Autodesk.Revit.Exceptions.ArgumentException) + { + //For some special cases, BoundarySegments of the element are not valid for CurveLoop creation + //(curveLoop.Append(curve) throws exception because "This curve will make the loop discontinuous.") + + return 0.0; + } + } + + double loopArea = ExporterIFCUtils.ComputeAreaOfCurveLoops(new List() { curveLoop }); + + if (area < loopArea) + area = loopArea; + } + + double length = UnitUtil.UnscaleLength(extrusionCreationData.ScaledLength); + + return area * length; + } + /// /// Gets the calculated double value. /// diff --git a/Source/Revit.IFC.Export/Exporter/PropertySet/Calculators/HeightCalculator.cs b/Source/Revit.IFC.Export/Exporter/PropertySet/Calculators/HeightCalculator.cs index c9b685db..2fe8be59 100644 --- a/Source/Revit.IFC.Export/Exporter/PropertySet/Calculators/HeightCalculator.cs +++ b/Source/Revit.IFC.Export/Exporter/PropertySet/Calculators/HeightCalculator.cs @@ -112,7 +112,7 @@ public static HeightCalculator Instance } else if (IFCAnyHandleUtil.IsSubTypeOf(hnd, IFCEntityType.IfcCurtainWall)) { - BoundingBoxXYZ boundingBox = (element as Wall).get_BoundingBox(null); + BoundingBoxXYZ boundingBox = element.get_BoundingBox(null); if (boundingBox != null) m_Height = boundingBox.Max.Z - boundingBox.Min.Z; } diff --git a/Source/Revit.IFC.Export/Exporter/PropertySet/Calculators/IsExternalCalculator.cs b/Source/Revit.IFC.Export/Exporter/PropertySet/Calculators/IsExternalCalculator.cs index eb80db16..60fb76d0 100644 --- a/Source/Revit.IFC.Export/Exporter/PropertySet/Calculators/IsExternalCalculator.cs +++ b/Source/Revit.IFC.Export/Exporter/PropertySet/Calculators/IsExternalCalculator.cs @@ -35,7 +35,7 @@ class IsExternalCalculator : PropertyCalculator /// /// A boolean variable to keep the calculated value. /// - private bool IsExternal { get; set; } = false; + private bool? IsExternal { get; set; } = false; /// /// The IsExternalCalculator instance. @@ -53,6 +53,10 @@ class IsExternalCalculator : PropertyCalculator public override bool Calculate(ExporterIFC exporterIFC, IFCExportBodyParams extrusionCreationData, Element element, ElementType elementType, EntryMap entryMap) { IsExternal = CategoryUtil.IsElementExternal(element); + + if (IsExternal == null) + return false; + return true; } @@ -62,7 +66,7 @@ public override bool Calculate(ExporterIFC exporterIFC, IFCExportBodyParams extr /// The boolean value. public override bool GetBooleanValue() { - return IsExternal; + return IsExternal ?? false; } } } \ No newline at end of file diff --git a/Source/Revit.IFC.Export/Exporter/PropertySet/Calculators/LengthCalculator.cs b/Source/Revit.IFC.Export/Exporter/PropertySet/Calculators/LengthCalculator.cs index 7e71caba..9dca4799 100644 --- a/Source/Revit.IFC.Export/Exporter/PropertySet/Calculators/LengthCalculator.cs +++ b/Source/Revit.IFC.Export/Exporter/PropertySet/Calculators/LengthCalculator.cs @@ -128,7 +128,7 @@ public override bool Calculate(ExporterIFC exporterIFC, IFCExportBodyParams extr // For Slab, length is the major edge of the rectangle area profile (get it from ScaledWidth) // Also for Stair support IFCAnyHandle hnd = ExporterCacheManager.ElementToHandleCache.Find(element.Id); - if (IFCAnyHandleUtil.IsSubTypeOf(hnd, IFCEntityType.IfcSlab) || + if (PropertyUtil.IsWidthLengthReversed(hnd) || CategoryUtil.GetSafeCategoryId(element).Value == (long)BuiltInCategory.OST_StairsStringerCarriage) { m_Length = extrusionCreationData.ScaledWidth; diff --git a/Source/Revit.IFC.Export/Exporter/PropertySet/Calculators/NetFloorAreaCalculator.cs b/Source/Revit.IFC.Export/Exporter/PropertySet/Calculators/NetFloorAreaCalculator.cs index b4eed18d..8c668bfc 100644 --- a/Source/Revit.IFC.Export/Exporter/PropertySet/Calculators/NetFloorAreaCalculator.cs +++ b/Source/Revit.IFC.Export/Exporter/PropertySet/Calculators/NetFloorAreaCalculator.cs @@ -79,6 +79,10 @@ public override bool Calculate(ExporterIFC exporterIFC, IFCExportBodyParams extr if (m_Area > MathUtil.Eps() * MathUtil.Eps()) return true; + m_Area = UnitUtil.ScaleArea(CalculateSpatialElementNetFloorArea(element as SpatialElement)); + if (m_Area > MathUtil.Eps() * MathUtil.Eps()) + return true; + ElementId categoryId = CategoryUtil.GetSafeCategoryId(element); IFCAnyHandle hnd = ExporterCacheManager.ElementToHandleCache.Find(element.Id); if (element is SpatialElement @@ -102,6 +106,53 @@ public override bool Calculate(ExporterIFC exporterIFC, IFCExportBodyParams extr return false; } + private double CalculateSpatialElementNetFloorArea(SpatialElement spatialElement) + { + double netFloorArea = 0.0; + + if (spatialElement == null) + return netFloorArea; + + // Get the boundary loops of the SpatialElement + IList> boundaryLoops = spatialElement.GetBoundarySegments(new SpatialElementBoundaryOptions()); + + double outerLoopArea = 0.0; + double loopsArea = 0.0; + foreach (IList boundaryLoop in boundaryLoops) + { + CurveLoop curveLoop = new CurveLoop(); + foreach (BoundarySegment boundarySegment in boundaryLoop) + { + try + { + Curve curve = boundarySegment.GetCurve(); + curveLoop.Append(curve); + } + catch (Autodesk.Revit.Exceptions.ArgumentException) + { + //For some special cases, BoundarySegments of the element are not valid for CurveLoop creation + //(curveLoop.Append(curve) throws exception because "This curve will make the loop discontinuous.") + + return 0.0; + } + } + + double loopArea = ExporterIFCUtils.ComputeAreaOfCurveLoops(new List() { curveLoop }); + + if (outerLoopArea < loopArea) + outerLoopArea = loopArea; + + loopsArea += loopArea; + } + + //To define the net area, we need to subtract the area of the holes from the area of the outerLoopArea. + //loopsArea is the sum of the areas of all the loops. + double innerLoopsArea = loopsArea - outerLoopArea; + netFloorArea = outerLoopArea - innerLoopsArea; + + return netFloorArea; + } + /// /// Gets the calculated double value. /// diff --git a/Source/Revit.IFC.Export/Exporter/PropertySet/Calculators/WidthCalculator.cs b/Source/Revit.IFC.Export/Exporter/PropertySet/Calculators/WidthCalculator.cs index 48e63f35..b18f988a 100644 --- a/Source/Revit.IFC.Export/Exporter/PropertySet/Calculators/WidthCalculator.cs +++ b/Source/Revit.IFC.Export/Exporter/PropertySet/Calculators/WidthCalculator.cs @@ -124,8 +124,8 @@ public override bool Calculate(ExporterIFC exporterIFC, IFCExportBodyParams extr if (extrusionCreationData == null) return false; - // For Slab width is the lesser edge of the rectangle area profile (get it from ScaledHeight) - if (IFCAnyHandleUtil.IsSubTypeOf(hnd, IFCEntityType.IfcSlab)) + // For Slab width is the length of the extrusion of the rectangle area profile (get it from ScaledHeight) + if (PropertyUtil.IsWidthLengthReversed(hnd)) { m_Width = extrusionCreationData.ScaledHeight; } diff --git a/Source/Revit.IFC.Export/Exporter/PropertySet/ClassificationUtil.cs b/Source/Revit.IFC.Export/Exporter/PropertySet/ClassificationUtil.cs index b3622164..bf04fb57 100644 --- a/Source/Revit.IFC.Export/Exporter/PropertySet/ClassificationUtil.cs +++ b/Source/Revit.IFC.Export/Exporter/PropertySet/ClassificationUtil.cs @@ -73,37 +73,39 @@ public static void CreateUniformatClassification(ExporterIFC exporterIFC, IFCFil // Create Uniformat classification, if it is not set. string uniformatKeyString = "Uniformat"; string uniformatDescription = ""; - string uniformatCode = null; - if (ParameterUtil.GetStringValueFromElementOrSymbol(element, BuiltInParameter.UNIFORMAT_CODE, false, out uniformatCode) == null) - ParameterUtil.GetStringValueFromElementOrSymbol(element, "Assembly Code", out uniformatCode); - - if (!String.IsNullOrWhiteSpace(uniformatCode)) - { - if (ParameterUtil.GetStringValueFromElementOrSymbol(element, BuiltInParameter.UNIFORMAT_DESCRIPTION, false, out uniformatDescription) == null) - ParameterUtil.GetStringValueFromElementOrSymbol(element, "Assembly Description", out uniformatDescription); - } if (!ExporterCacheManager.ClassificationCache.ClassificationHandles.TryGetValue(uniformatKeyString, out IFCAnyHandle classification)) { - classification = IFCInstanceExporter.CreateClassification(file, "CSI (Construction Specifications Institute)", "1998", 0, 0, 0, + classification = IFCInstanceExporter.CreateClassification(file, "CSI (Construction Specifications Institute)", "1998", 0, 0, 0, uniformatKeyString, "UniFormat Classification", GetUniformatURL()); ExporterCacheManager.ClassificationCache.ClassificationHandles.Add(uniformatKeyString, classification); } - if (!String.IsNullOrEmpty(uniformatCode)) + + foreach (IFCAnyHandle elemHnd in elemHnds) { + if (!IFCAnyHandleUtil.IsSubTypeOf(elemHnd, constraintEntType)) + continue; + + ElementId elementId = ExporterCacheManager.HandleToElementCache.Find(elemHnd); + Element elementToUse = (elementId == ElementId.InvalidElementId) ? element : element?.Document?.GetElement(elementId); + if (elementToUse == null) + continue; + + if (ParameterUtil.GetStringValueFromElementOrSymbol(elementToUse, BuiltInParameter.UNIFORMAT_CODE, false, out string uniformatCode) == null) + ParameterUtil.GetStringValueFromElementOrSymbol(elementToUse, "Assembly Code", out uniformatCode); + + if (!String.IsNullOrWhiteSpace(uniformatCode)) { - foreach (IFCAnyHandle elemHnd in elemHnds) - { - if (IFCAnyHandleUtil.IsSubTypeOf(elemHnd, constraintEntType)) - { - ClassificationReferenceKey key = new ClassificationReferenceKey(GetUniformatURL(), - uniformatCode, uniformatKeyString, uniformatDescription, classification); - InsertClassificationReference(file, key, elemHnd); - } - } + if (ParameterUtil.GetStringValueFromElementOrSymbol(elementToUse, BuiltInParameter.UNIFORMAT_DESCRIPTION, false, out string uniformatRefName) == null) + ParameterUtil.GetStringValueFromElementOrSymbol(elementToUse, "Assembly Description", out uniformatRefName); + + ClassificationReferenceKey key = new ClassificationReferenceKey(GetUniformatURL(), + uniformatCode, uniformatRefName, uniformatDescription, classification); + InsertClassificationReference(file, key, elemHnd); } } + } /// @@ -162,15 +164,15 @@ public static void CreateUniformatClassification(ExporterIFC exporterIFC, IFCFil ParseClassificationCode(paramClassificationCode, classificationCodeFieldName, out classificationName, out classificationCode, out classificationRefName); - if (string.IsNullOrEmpty(classificationDescription)) + if (string.IsNullOrEmpty(classificationRefName)) { if (string.Compare(classificationCodeFieldName, "Assembly Code", true) == 0) { - ParameterUtil.GetStringValueFromElementOrSymbol(element, elementType, BuiltInParameter.UNIFORMAT_DESCRIPTION, false, out classificationDescription); + ParameterUtil.GetStringValueFromElementOrSymbol(element, elementType, BuiltInParameter.UNIFORMAT_DESCRIPTION, false, out classificationRefName); } else if (string.Compare(classificationCodeFieldName, "OmniClass Number", true) == 0) { - ParameterUtil.GetStringValueFromElementOrSymbol(element, elementType, BuiltInParameter.OMNICLASS_DESCRIPTION, false, out classificationDescription); + ParameterUtil.GetStringValueFromElementOrSymbol(element, elementType, BuiltInParameter.OMNICLASS_DESCRIPTION, false, out classificationRefName); } } // If classificationName is empty, there is no classification to export. diff --git a/Source/Revit.IFC.Export/Exporter/PropertySet/Description.cs b/Source/Revit.IFC.Export/Exporter/PropertySet/Description.cs index a89c9d60..3b5dd7ba 100644 --- a/Source/Revit.IFC.Export/Exporter/PropertySet/Description.cs +++ b/Source/Revit.IFC.Export/Exporter/PropertySet/Description.cs @@ -171,28 +171,25 @@ public bool IsAppropriateObjectType(IFCAnyHandle handle) { if (handle == null) return false; - //if (ObjectType == "") - // return true; - + // ObjectType information comes from PSD's Applicable Type. This may be a comma separated list of applicable type IFCEntityType hndEntity = IFCAnyHandleUtil.GetEntityType(handle); - if (ObjectType.IndexOf(hndEntity.ToString(), StringComparison.InvariantCultureIgnoreCase) < 0) + if (ObjectType.IndexOf(hndEntity.ToString(), + StringComparison.InvariantCultureIgnoreCase) >= 0) + { + return true; + } + + // The use of ObjectType in the PSD is confusing at best. The purpose and its consistency is questionable. + // If the entity is not found in this ObjectType, try the "old" way to compare the ObjectType attribute value + string objectType = IFCAnyHandleUtil.GetObjectType(handle); + if (string.IsNullOrEmpty(objectType)) { - // The use of ObjectType in the PSD is confusing at best. The purpose and its consistency is questionable. - // If the entity is not found in this ObjectType, try the "old" way to compare the ObjectType attribute value - string objectType = IFCAnyHandleUtil.GetObjectType(handle); - if (!string.IsNullOrEmpty(objectType)) - { - if (ObjectType.IndexOf(objectType, StringComparison.InvariantCultureIgnoreCase) < 0) - return false; - else - return true; - } return false; } - else - return true; - //return (NamingUtil.IsEqualIgnoringCaseAndSpaces(ObjectType, objectType)); + + return ObjectType.IndexOf(objectType, + StringComparison.InvariantCultureIgnoreCase) >= 0; } /// @@ -208,13 +205,8 @@ public bool IsAppropriateObjectType(IFCEntityType entityType) return false; // ObjectType information comes from PSD's Applicable Type. This may be a comma separated list of applicable type - if (ObjectType.IndexOf(entityType.ToString(), StringComparison.InvariantCultureIgnoreCase) < 0) - return false; - else - return true; - - //string objectType = IFCAnyHandleUtil.GetObjectType(handle); - //return (NamingUtil.IsEqualIgnoringCaseAndSpaces(ObjectType, objectType)); + return ObjectType.IndexOf(entityType.ToString(), + StringComparison.InvariantCultureIgnoreCase) >= 0; } } } diff --git a/Source/Revit.IFC.Export/Exporter/PropertySet/ElectricalCurrentPropertyUtil.cs b/Source/Revit.IFC.Export/Exporter/PropertySet/ElectricalCurrentPropertyUtil.cs deleted file mode 100644 index 41caed4c..00000000 --- a/Source/Revit.IFC.Export/Exporter/PropertySet/ElectricalCurrentPropertyUtil.cs +++ /dev/null @@ -1,121 +0,0 @@ -// -// BIM IFC library: this library works with Autodesk(R) Revit(R) to export IFC files containing model geometry. -// Copyright (C) 2012 Autodesk, Inc. -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Autodesk.Revit.DB; -using Autodesk.Revit.DB.IFC; -using Revit.IFC.Export.Utility; -using Revit.IFC.Export.Toolkit; -using Revit.IFC.Common.Utility; - -namespace Revit.IFC.Export.Exporter.PropertySet -{ - /// - /// Provides static methods to create varies IFC properties. - /// - public class ElectricalCurrentPropertyUtil : PropertyUtil - { - /// - /// Create a label property. - /// - /// The IFC file. - /// The name of the property. - /// The value of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateElectricalCurrentMeasureProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) - { - switch (valueType) - { - case PropertyValueType.EnumeratedValue: - { - IList valueList = new List(); - valueList.Add(IFCDataUtil.CreateAsElectricCurrentMeasure(value)); - return IFCInstanceExporter.CreatePropertyEnumeratedValue(file, propertyName, null, valueList, null); - } - case PropertyValueType.SingleValue: - return IFCInstanceExporter.CreatePropertySingleValue(file, propertyName, null, IFCDataUtil.CreateAsElectricCurrentMeasure(value), null); - default: - throw new InvalidOperationException("Missing case!"); - } - } - - /// - /// Create a label property, or retrieve from cache. - /// - /// The IFC file. - /// The name of the property. - /// The value of the property. - /// The value type of the property. - /// The created or cached property handle. - public static IFCAnyHandle CreateElectricalCurrentMeasurePropertyFromCache(IFCFile file, string propertyName, double value, PropertyValueType valueType) - { - // We have a partial cache here - we will only cache multiples of 15 degrees. - bool canCache = false; - double ampsDiv5 = Math.Floor(value / 5.0 + 0.5); - double integerAmps = ampsDiv5 * 5.0; - if (MathUtil.IsAlmostEqual(value, integerAmps)) - { - canCache = true; - value = integerAmps; - } - - IFCAnyHandle propertyHandle; - if (canCache) - { - propertyHandle = ExporterCacheManager.PropertyInfoCache.ElectricCurrentCache.Find(propertyName, value); - if (propertyHandle != null) - return propertyHandle; - } - - propertyHandle = CreateElectricalCurrentMeasureProperty(file, propertyName, value, valueType); - - if (canCache && !IFCAnyHandleUtil.IsNullOrHasNoValue(propertyHandle)) - { - ExporterCacheManager.PropertyInfoCache.ElectricCurrentCache.Add(propertyName, value, propertyHandle); - } - - return propertyHandle; - } - - /// - /// Create an electrical current measure property from the element's or type's parameter. - /// - /// The IFC file. - /// The Element. - /// The name of the parameter. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateElectricalCurrentMeasurePropertyFromElement(IFCFile file, Element elem, string revitParameterName, string ifcPropertyName, PropertyValueType valueType) - { - double propertyValue; - if (ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue) != null) - { - propertyValue = UnitUtil.ScaleElectricCurrent(propertyValue); - return CreateElectricalCurrentMeasurePropertyFromCache(file, ifcPropertyName, propertyValue, valueType); - } - - return null; - } - } -} diff --git a/Source/Revit.IFC.Export/Exporter/PropertySet/ElectricalVoltagePropertyUtil.cs b/Source/Revit.IFC.Export/Exporter/PropertySet/ElectricalVoltagePropertyUtil.cs deleted file mode 100644 index c6edf85e..00000000 --- a/Source/Revit.IFC.Export/Exporter/PropertySet/ElectricalVoltagePropertyUtil.cs +++ /dev/null @@ -1,121 +0,0 @@ -// -// BIM IFC library: this library works with Autodesk(R) Revit(R) to export IFC files containing model geometry. -// Copyright (C) 2012 Autodesk, Inc. -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Autodesk.Revit.DB; -using Autodesk.Revit.DB.IFC; -using Revit.IFC.Export.Utility; -using Revit.IFC.Export.Toolkit; -using Revit.IFC.Common.Utility; - -namespace Revit.IFC.Export.Exporter.PropertySet -{ - /// - /// Provides static methods to create varies IFC properties. - /// - public class ElectricVoltagePropertyUtil : PropertyUtil - { - /// - /// Create a label property. - /// - /// The IFC file. - /// The name of the property. - /// The value of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateElectricVoltageMeasureProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) - { - IFCData electricalVoltageData = IFCDataUtil.CreateAsElectricVoltageMeasure(value); - return CreateCommonProperty(file, propertyName, electricalVoltageData, valueType, null); - } - - /// - /// Create a label property, or retrieve from cache. - /// - /// The IFC file. - /// The name of the property. - /// The value of the property. - /// The value type of the property. - /// The created or cached property handle. - public static IFCAnyHandle CreateElectricalVoltageMeasurePropertyFromCache(IFCFile file, string propertyName, double value, PropertyValueType valueType) - { - // We have a partial cache here - we will only cache multiples of 15 degrees. - bool canCache = false; - double ampsDiv5 = Math.Floor(value / 5.0 + 0.5); - double integerAmps = ampsDiv5 * 5.0; - if (MathUtil.IsAlmostEqual(value, integerAmps)) - { - canCache = true; - value = integerAmps; - } - - IFCAnyHandle propertyHandle; - if (canCache) - { - propertyHandle = ExporterCacheManager.PropertyInfoCache.ElectricVoltageCache.Find(propertyName, value); - if (propertyHandle != null) - return propertyHandle; - } - - propertyHandle = CreateElectricVoltageMeasureProperty(file, propertyName, value, valueType); - - if (canCache && !IFCAnyHandleUtil.IsNullOrHasNoValue(propertyHandle)) - { - ExporterCacheManager.PropertyInfoCache.ElectricVoltageCache.Add(propertyName, value, propertyHandle); - } - - return propertyHandle; - } - - /// - /// Create an electrical voltage measure property from the element's parameter. - /// - /// The IFC file. - /// The Element. - /// The name of the parameter. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateElectricVoltageMeasurePropertyFromElement(IFCFile file, Element elem, string revitParameterName, string ifcPropertyName, PropertyValueType valueType) - { - double propertyValue; - Parameter param = ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue); - if ( param != null) - { - if (!ParameterUtil.ParameterDataTypeIsEqualTo(param, SpecTypeId.Number)) - propertyValue = UnitUtil.ScaleElectricVoltage(propertyValue); - - if (valueType == PropertyValueType.BoundedValue) - { - IList boundedData = GetBoundedDataFromElement(elem, revitParameterName, propertyValue, SpecTypeId.ElectricalPotential, "IfcElectricVoltageMeasure"); - return CreateBoundedValuePropertyFromList(file, ifcPropertyName, boundedData, null); - } - else - { - return CreateElectricalVoltageMeasurePropertyFromCache(file, ifcPropertyName, propertyValue, valueType); - } - } - - return null; - } - } -} diff --git a/Source/Revit.IFC.Export/Exporter/PropertySet/FrequencyPropertyUtil.cs b/Source/Revit.IFC.Export/Exporter/PropertySet/FrequencyPropertyUtil.cs deleted file mode 100644 index dc2967ba..00000000 --- a/Source/Revit.IFC.Export/Exporter/PropertySet/FrequencyPropertyUtil.cs +++ /dev/null @@ -1,107 +0,0 @@ -// -// BIM IFC library: this library works with Autodesk(R) Revit(R) to export IFC files containing model geometry. -// Copyright (C) 2012 Autodesk, Inc. -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Autodesk.Revit.DB; -using Autodesk.Revit.DB.IFC; -using Revit.IFC.Export.Utility; -using Revit.IFC.Export.Toolkit; -using Revit.IFC.Common.Utility; - -namespace Revit.IFC.Export.Exporter.PropertySet -{ - /// - /// Provides static methods to create varies IFC properties. Inherit from PropertyUtil for protected helper functions. - /// - public class FrequencyPropertyUtil : PropertyUtil - { - /// Create a FrequencyMeasure property. - /// The IFC file. - /// The name of the property. - /// The value of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateFrequencyProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) - { - IFCData frequencyData = IFCDataUtil.CreateAsFrequencyMeasure(value); - return CreateCommonProperty(file, propertyName, frequencyData, valueType, null); - } - - /// - /// Create a Frequency measure property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateFrequencyPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) - { - double propertyValue; - if (ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue) != null) - { - if (valueType == PropertyValueType.BoundedValue) - { - IList boundedData = GetBoundedDataFromElement(elem, revitParameterName, propertyValue, SpecTypeId.Number, "IfcFrequencyMeasure"); - return CreateBoundedValuePropertyFromList(file, ifcPropertyName, boundedData, null); - } - else - { - return CreateFrequencyProperty(file, ifcPropertyName, propertyValue, valueType); - } - } - return null; - } - - /// - /// Create a Frequency measure property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateFrequencyPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) - { - IFCAnyHandle propHnd = CreateFrequencyPropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; - - if (revitBuiltInParam != BuiltInParameter.INVALID) - { - string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateFrequencyPropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; - } - - return null; - } - } -} \ No newline at end of file diff --git a/Source/Revit.IFC.Export/Exporter/PropertySet/PositivePlaneAnglePropertyUtil.cs b/Source/Revit.IFC.Export/Exporter/PropertySet/PositivePlaneAnglePropertyUtil.cs deleted file mode 100644 index 52041095..00000000 --- a/Source/Revit.IFC.Export/Exporter/PropertySet/PositivePlaneAnglePropertyUtil.cs +++ /dev/null @@ -1,136 +0,0 @@ -// -// BIM IFC library: this library works with Autodesk(R) Revit(R) to export IFC files containing model geometry. -// Copyright (C) 2012 Autodesk, Inc. -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Autodesk.Revit.DB; -using Autodesk.Revit.DB.IFC; -using Revit.IFC.Export.Utility; -using Revit.IFC.Export.Toolkit; -using Revit.IFC.Common.Utility; - -namespace Revit.IFC.Export.Exporter.PropertySet -{ - /// - /// Provides static methods to create varies IFC properties. - /// - public class PositivePlaneAnglePropertyUtil : PropertyUtil - { - /// - /// Create a label property. - /// - /// The IFC file. - /// The name of the property. - /// The value of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreatePositivePlaneAngleMeasureProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) - { - // Ensure it is positive. Don't throw, but should tell user. - if (value <= MathUtil.Eps()) - return null; - - switch (valueType) - { - case PropertyValueType.EnumeratedValue: - { - IList valueList = new List(); - valueList.Add(IFCDataUtil.CreateAsPositivePlaneAngleMeasure(value)); - return IFCInstanceExporter.CreatePropertyEnumeratedValue(file, propertyName, null, valueList, null); - } - case PropertyValueType.SingleValue: - return IFCInstanceExporter.CreatePropertySingleValue(file, propertyName, null, IFCDataUtil.CreateAsPositivePlaneAngleMeasure(value), null); - default: - throw new InvalidOperationException("Missing case!"); - } - } - - /// - /// Create a label property, or retrieve from cache. - /// - /// The IFC file. - /// The name of the property. - /// The value of the property. - /// The value type of the property. - /// The created or cached property handle. - public static IFCAnyHandle CreatePositivePlaneAngleMeasurePropertyFromCache(IFCFile file, string propertyName, double value, PropertyValueType valueType) - { - // We have a partial cache here - we will only cache multiples of 15 degrees. - bool canCache = false; - double degreesDiv15 = Math.Floor(value / 15.0 + 0.5); - double integerDegrees = degreesDiv15 * 15.0; - if (MathUtil.IsAlmostEqual(value, integerDegrees)) - { - canCache = true; - value = integerDegrees; - } - - IFCAnyHandle propertyHandle; - if (canCache) - { - propertyHandle = ExporterCacheManager.PropertyInfoCache.PositivePlaneAngleCache.Find(propertyName, value); - if (propertyHandle != null) - return propertyHandle; - } - - propertyHandle = CreatePositivePlaneAngleMeasureProperty(file, propertyName, value, valueType); - - if (canCache && !IFCAnyHandleUtil.IsNullOrHasNoValue(propertyHandle)) - { - ExporterCacheManager.PropertyInfoCache.PositivePlaneAngleCache.Add(propertyName, value, propertyHandle); - } - - return propertyHandle; - } - - /// - /// Create a plane angle measure property from the element's parameter. - /// - /// The IFC file. - /// The Element. - /// The name of the parameter. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreatePositivePlaneAngleMeasurePropertyFromElement(IFCFile file, Element elem, string revitParameterName, string ifcPropertyName, PropertyValueType valueType) - { - double propertyValue; - Parameter param = ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue); - if (param != null) - { - if (!ParameterUtil.ParameterDataTypeIsEqualTo(param, SpecTypeId.Number)) - propertyValue = UnitUtil.ScaleAngle(propertyValue); - - if (valueType == PropertyValueType.BoundedValue) - { - IList boundedData = GetBoundedDataFromElement(elem, revitParameterName, propertyValue, SpecTypeId.Angle, "IfcPositivePlaneAngleMeasure"); - return CreateBoundedValuePropertyFromList(file, ifcPropertyName, boundedData, null); - } - else - { - return CreatePositivePlaneAngleMeasurePropertyFromCache(file, ifcPropertyName, propertyValue, valueType); - } - } - - return null; - } - } -} \ No newline at end of file diff --git a/Source/Revit.IFC.Export/Exporter/PropertySet/PreDefinedPropertySetEntry.cs b/Source/Revit.IFC.Export/Exporter/PropertySet/PreDefinedPropertySetEntry.cs index 8d1f7d9d..c8538bdc 100644 --- a/Source/Revit.IFC.Export/Exporter/PropertySet/PreDefinedPropertySetEntry.cs +++ b/Source/Revit.IFC.Export/Exporter/PropertySet/PreDefinedPropertySetEntry.cs @@ -21,8 +21,6 @@ using System.Collections.Generic; using Autodesk.Revit.DB; using Autodesk.Revit.DB.IFC; -using Revit.IFC.Export.Utility; -using GeometryGym.Ifc; namespace Revit.IFC.Export.Exporter.PropertySet { diff --git a/Source/Revit.IFC.Export/Exporter/PropertySet/PropertySetEntry.cs b/Source/Revit.IFC.Export/Exporter/PropertySet/PropertySetEntry.cs index f509c0e7..fc3121ef 100644 --- a/Source/Revit.IFC.Export/Exporter/PropertySet/PropertySetEntry.cs +++ b/Source/Revit.IFC.Export/Exporter/PropertySet/PropertySetEntry.cs @@ -22,7 +22,6 @@ using Autodesk.Revit.DB; using Autodesk.Revit.DB.IFC; using Revit.IFC.Export.Utility; -using GeometryGym.Ifc; namespace Revit.IFC.Export.Exporter.PropertySet { @@ -264,10 +263,41 @@ public enum PropertyType AngularVelocity, IfcCostValue, IfcRelaxation, - ElectricalResistivity, FrictionLoss, LinearMoment, - LinearStiffness + LinearStiffness, + CostPerArea, + ApparentPowerDensity, + CostRateEnergy, + CostRatePower, + Efficacy, + Luminance, + ElectricalPowerDensity, + PowerPerLength, + ElectricalResistivity, + HeatCapacityPerArea, + ThermalGradientCoefficientForMoistureCapacity, + ThermalMass, + AirFlowDensity, + AirFlowDividedByCoolingLoad, + AirFlowDividedByVolume, + AreaDividedByCoolingLoad, + AreaDividedByHeatingLoad, + CoolingLoadDividedByArea, + CoolingLoadDividedByVolume, + FlowPerPower, + HvacFriction, + HeatingLoadDividedByArea, + HeatingLoadDividedByVolume, + PowerPerFlow, + PipingFriction, + AreaSpringCoefficient, + LineSpringCoefficient, + MassPerUnitArea, + ReinforcementAreaPerUnitLength, + RotationalLineSpringCoefficient, + RotationalPointSpringCoefficient, + UnitWeight } /// @@ -297,8 +327,6 @@ public class PropertySetEntry : Entry IFCAnyHandle DefaultProperty { get; set; } = null; - public IfcValue DefaultValue { get; set; } = null; - public IList CombinedParameterData { get; set; } = null; /// @@ -342,28 +370,6 @@ public PropertySetEntry(PropertyType propertyType, string propertyName, IEnumera { PropertyType = propertyType; } - - private IFCAnyHandle SetDefaultProperty(IFCFile file) - { - if (DefaultProperty == null) - { - if (DefaultValue != null) - { - switch (PropertyType) - { - case PropertyType.Label: - return DefaultProperty = PropertyUtil.CreateLabelProperty(file, PropertyName, DefaultValue.ValueString, PropertyValueType, PropertyEnumerationType); - case PropertyType.Text: - return DefaultProperty = PropertyUtil.CreateTextProperty(file, PropertyName, DefaultValue.ValueString, PropertyValueType); - case PropertyType.Identifier: - return DefaultProperty = PropertyUtil.CreateIdentifierProperty(file, PropertyName, DefaultValue.ValueString, PropertyValueType); - //todo make this work for all values - } - } - } - - return DefaultProperty; - } private string GetParameterValueById(Element element, ElementId paramId) { @@ -433,7 +439,7 @@ private IFCAnyHandle CreateTextPropertyFromCombinedParameterData(IFCFile file, E return propHnd; } - return SetDefaultProperty(file); + return null; } /// @@ -923,10 +929,6 @@ public static PropertySetEntry CreateParameterEntry(Parameter parameter, BuiltIn { propertyType = PropertyType.Currency; } - else if (type == SpecTypeId.Efficacy) - { - propertyType = PropertyType.ElectricalEfficacy; - } else if (type == SpecTypeId.Energy || type == SpecTypeId.HvacEnergy) { @@ -958,19 +960,11 @@ public static PropertySetEntry CreateParameterEntry(Parameter parameter, BuiltIn { propertyType = PropertyType.ElectricVoltage; } - else if (type == SpecTypeId.ElectricalResistivity) - { - propertyType = PropertyType.ElectricalResistivity; - } else if (type == SpecTypeId.ElectricalFrequency || type == SpecTypeId.StructuralFrequency) { propertyType = PropertyType.Frequency; } - else if (type == SpecTypeId.HvacFriction) - { - propertyType = PropertyType.FrictionLoss; - } else if (type == SpecTypeId.LuminousFlux) { propertyType = PropertyType.LuminousFlux; @@ -1126,6 +1120,134 @@ public static PropertySetEntry CreateParameterEntry(Parameter parameter, BuiltIn { propertyType = PropertyType.WarpingConstant; } + else if (type == SpecTypeId.CostPerArea) + { + propertyType = PropertyType.CostPerArea; + } + else if (type == SpecTypeId.ApparentPowerDensity) + { + propertyType = PropertyType.ApparentPowerDensity; + } + else if (type == SpecTypeId.CostRateEnergy) + { + propertyType = PropertyType.CostRateEnergy; + } + else if (type == SpecTypeId.CostRatePower) + { + propertyType = PropertyType.CostRatePower; + } + else if (type == SpecTypeId.Efficacy) + { + propertyType = PropertyType.ElectricalEfficacy; + } + else if (type == SpecTypeId.Luminance) + { + propertyType = PropertyType.Luminance; + } + else if (type == SpecTypeId.ElectricalPowerDensity) + { + propertyType = PropertyType.ElectricalPowerDensity; + } + else if (type == SpecTypeId.PowerPerLength) + { + propertyType = PropertyType.PowerPerLength; + } + else if (type == SpecTypeId.ElectricalResistivity) + { + propertyType = PropertyType.ElectricalResistivity; + } + else if (type == SpecTypeId.HeatCapacityPerArea) + { + propertyType = PropertyType.HeatCapacityPerArea; + } + else if (type == SpecTypeId.ThermalGradientCoefficientForMoistureCapacity) + { + propertyType = PropertyType.ThermalGradientCoefficientForMoistureCapacity; + } + else if (type == SpecTypeId.ThermalMass) + { + propertyType = PropertyType.ThermalMass; + } + else if (type == SpecTypeId.AirFlowDensity) + { + propertyType = PropertyType.AirFlowDensity; + } + else if (type == SpecTypeId.AirFlowDividedByCoolingLoad) + { + propertyType = PropertyType.AirFlowDividedByCoolingLoad; + } + else if (type == SpecTypeId.AirFlowDividedByVolume) + { + propertyType = PropertyType.AirFlowDividedByVolume; + } + else if (type == SpecTypeId.AreaDividedByCoolingLoad) + { + propertyType = PropertyType.AreaDividedByCoolingLoad; + } + else if (type == SpecTypeId.AreaDividedByHeatingLoad) + { + propertyType = PropertyType.AreaDividedByHeatingLoad; + } + else if (type == SpecTypeId.CoolingLoadDividedByArea) + { + propertyType = PropertyType.CoolingLoadDividedByArea; + } + else if (type == SpecTypeId.CoolingLoadDividedByVolume) + { + propertyType = PropertyType.CoolingLoadDividedByVolume; + } + else if (type == SpecTypeId.FlowPerPower) + { + propertyType = PropertyType.FlowPerPower; + } + else if (type == SpecTypeId.HvacFriction) + { + propertyType = PropertyType.FrictionLoss; + } + else if (type == SpecTypeId.HeatingLoadDividedByArea) + { + propertyType = PropertyType.HeatingLoadDividedByArea; + } + else if (type == SpecTypeId.HeatingLoadDividedByVolume) + { + propertyType = PropertyType.HeatingLoadDividedByVolume; + } + else if (type == SpecTypeId.PowerPerFlow) + { + propertyType = PropertyType.PowerPerFlow; + } + else if (type == SpecTypeId.PipingFriction) + { + propertyType = PropertyType.PipingFriction; + } + else if (type == SpecTypeId.AreaSpringCoefficient) + { + propertyType = PropertyType.AreaSpringCoefficient; + } + else if (type == SpecTypeId.LineSpringCoefficient) + { + propertyType = PropertyType.LineSpringCoefficient; + } + else if (type == SpecTypeId.MassPerUnitArea) + { + propertyType = PropertyType.MassPerUnitArea; + } + else if (type == SpecTypeId.ReinforcementAreaPerUnitLength) + { + propertyType = PropertyType.ReinforcementAreaPerUnitLength; + } + else if (type == SpecTypeId.RotationalLineSpringCoefficient) + { + propertyType = PropertyType.RotationalLineSpringCoefficient; + } + else if (type == SpecTypeId.RotationalPointSpringCoefficient) + { + propertyType = PropertyType.RotationalPointSpringCoefficient; + } + else if (type == SpecTypeId.UnitWeight) + { + propertyType = PropertyType.UnitWeight; + } else { assigned = false; diff --git a/Source/Revit.IFC.Export/Exporter/PropertySet/PropertySetEntryMap.cs b/Source/Revit.IFC.Export/Exporter/PropertySet/PropertySetEntryMap.cs index 35a6c023..4fbb477f 100644 --- a/Source/Revit.IFC.Export/Exporter/PropertySet/PropertySetEntryMap.cs +++ b/Source/Revit.IFC.Export/Exporter/PropertySet/PropertySetEntryMap.cs @@ -127,7 +127,7 @@ private static IFCData GetPropertyDataFromString(string valueString, PropertyTyp case PropertyType.AreaDensity: { if (double.TryParse(valueString, out double value)) - data = IFCDataUtil.CreateAsMeasure(value, "IfcAreaDensityMeasure"); + data = IFCDataUtil.CreateAsAreaDensityMeasure(value); break; } case PropertyType.Boolean: @@ -143,7 +143,7 @@ private static IFCData GetPropertyDataFromString(string valueString, PropertyTyp case PropertyType.ColorTemperature: { if (double.TryParse(valueString, out double value)) - data = IFCDataUtil.CreateAsMeasure(value, "IfcReal"); + data = IFCDataUtil.CreateAsReal(value); break; } case PropertyType.Count: @@ -157,14 +157,14 @@ private static IFCData GetPropertyDataFromString(string valueString, PropertyTyp if (double.TryParse(valueString, out double value)) { data = ExporterCacheManager.UnitsCache.ContainsKey("CURRENCY") ? - IFCDataUtil.CreateAsMeasure(value, "IfcMonetaryMeasure") : IFCDataUtil.CreateAsMeasure(value, "IfcReal"); + IFCDataUtil.CreateAsMonetaryMeasure(value) : IFCDataUtil.CreateAsReal(value); } break; } case PropertyType.ElectricalEfficacy: { if (double.TryParse(valueString, out double value)) - data = IFCDataUtil.CreateAsMeasure(value, "IfcReal"); + data = IFCDataUtil.CreateAsReal(value); break; } case PropertyType.ElectricCurrent: @@ -182,7 +182,7 @@ private static IFCData GetPropertyDataFromString(string valueString, PropertyTyp case PropertyType.Force: { if (Double.TryParse(valueString, out double value)) - data = IFCDataUtil.CreateAsMeasure(value, "IfcForceMeasure"); + data = IFCDataUtil.CreateAsForceMeasure(value); break; } case PropertyType.Frequency: @@ -205,13 +205,13 @@ private static IFCData GetPropertyDataFromString(string valueString, PropertyTyp case PropertyType.Illuminance: { if (Double.TryParse(valueString, out double value)) - data = IFCDataUtil.CreateAsMeasure(value, "IfcIlluminanceMeasure"); + data = IFCDataUtil.CreateAsIlluminanceMeasure(value); break; } case PropertyType.HeatFluxDensity: { if (Double.TryParse(valueString, out double value)) - data = IFCDataUtil.CreateAsMeasure(value, "IfcHeatFluxDensityMeasure"); + data = IFCDataUtil.CreateAsHeatFluxDensityMeasure(value); break; } case PropertyType.Label: @@ -228,7 +228,7 @@ private static IFCData GetPropertyDataFromString(string valueString, PropertyTyp case PropertyType.LinearVelocity: { if (Double.TryParse(valueString, out double value)) - data = IFCDataUtil.CreateAsMeasure(value, "IfcLinearVelocityMeasure"); + data = IFCDataUtil.CreateAsLinearVelocityMeasure(value); break; } case PropertyType.Logical: @@ -240,43 +240,43 @@ private static IFCData GetPropertyDataFromString(string valueString, PropertyTyp case PropertyType.LuminousFlux: { if (Double.TryParse(valueString, out double value)) - data = IFCDataUtil.CreateAsMeasure(value, "IfcLuminousFluxMeasure"); + data = IFCDataUtil.CreateAsLuminousFluxMeasure(value); break; } case PropertyType.LuminousIntensity: { if (Double.TryParse(valueString, out double value)) - data = IFCDataUtil.CreateAsMeasure(value, "IfcLuminousIntensityMeasure"); + data = IFCDataUtil.CreateAsLuminousIntensityMeasure(value); break; } case PropertyType.LinearForce: { if (Double.TryParse(valueString, out double value)) - data = IFCDataUtil.CreateAsMeasure(value, "IfcLinearForceMeasure"); + data = IFCDataUtil.CreateAsLinearForceMeasure(value); break; } case PropertyType.Mass: { if (Double.TryParse(valueString, out double value)) - data = IFCDataUtil.CreateAsMeasure(value, "IfcMassMeasure"); + data = IFCDataUtil.CreateAsMassMeasure(value); break; } case PropertyType.MassDensity: { if (Double.TryParse(valueString, out double value)) - data = IFCDataUtil.CreateAsMeasure(value, "IfcMassDensityMeasure"); + data = IFCDataUtil.CreateAsMassDensityMeasure(value); break; } case PropertyType.MassFlowRate: { if (Double.TryParse(valueString, out double value)) - data = IFCDataUtil.CreateAsMeasure(value, "IfcMassFlowRateMeasure"); + data = IFCDataUtil.CreateAsMassFlowRateMeasure(value); break; } case PropertyType.ModulusOfElasticity: { if (Double.TryParse(valueString, out double value)) - data = IFCDataUtil.CreateAsMeasure(value, "IfcModulusOfElasticityMeasure"); + data = IFCDataUtil.CreateAsModulusOfElasticityMeasure(value); break; } case PropertyType.NormalisedRatio: @@ -299,7 +299,7 @@ private static IFCData GetPropertyDataFromString(string valueString, PropertyTyp case PropertyType.PlanarForce: { if (Double.TryParse(valueString, out double value)) - data = IFCDataUtil.CreateAsMeasure(value, "IfcPlanarForceMeasure"); + data = IFCDataUtil.CreateAsPlanarForceMeasure(value); break; } case PropertyType.PositiveLength: @@ -328,7 +328,7 @@ private static IFCData GetPropertyDataFromString(string valueString, PropertyTyp case PropertyType.Pressure: { if (Double.TryParse(valueString, out double value)) - data = IFCDataUtil.CreateAsMeasure(value, "IfcPressureMeasure"); + data = IFCDataUtil.CreateAsPressureMeasure(value); break; } case PropertyType.Ratio: @@ -345,7 +345,7 @@ private static IFCData GetPropertyDataFromString(string valueString, PropertyTyp case PropertyType.RotationalFrequency: { if (Double.TryParse(valueString, out double value)) - data = IFCDataUtil.CreateAsMeasure(value, "IfcRotationalFrequencyMeasure"); + data = IFCDataUtil.CreateAsRotationalFrequencyMeasure(value); break; } case PropertyType.SoundPower: @@ -387,13 +387,13 @@ private static IFCData GetPropertyDataFromString(string valueString, PropertyTyp case PropertyType.VolumetricFlowRate: { if (Double.TryParse(valueString, out double value)) - data = IFCDataUtil.CreateAsMeasure(value, "IfcVolumetricFlowRateMeasure"); + data = IFCDataUtil.CreateAsVolumetricFlowRateMeasure(value); break; } case PropertyType.Time: { if (Double.TryParse(valueString, out double value)) - data = IFCDataUtil.CreateAsMeasure(value, "IfcTimeMeasure"); + data = IFCDataUtil.CreateAsTimeMeasure(value); break; } // Known unhandled cases: @@ -438,26 +438,26 @@ private static IFCData GetPropertyDataFromString(string valueString, PropertyTyp { case PropertyType.Area: { - propHnd = PropertyUtil.CreateAreaMeasurePropertyFromElement(file, exporterIFC, element, revitParamNameToUse, + propHnd = PropertyUtil.CreateAreaPropertyFromElement(file, element, revitParamNameToUse, builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.Acceleration: { - propHnd = PropertyUtil.CreateAccelerationMeasurePropertyFromElement(file, exporterIFC, element, revitParamNameToUse, + propHnd = PropertyUtil.CreateAccelerationPropertyFromElement(file, element, revitParamNameToUse, builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.AngularVelocity: { - propHnd = PropertyUtil.CreateAngularVelocityMeasurePropertyFromElement(file, exporterIFC, element, revitParamNameToUse, + propHnd = PropertyUtil.CreateAngularVelocityPropertyFromElement(file, element, revitParamNameToUse, builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.AreaDensity: { - propHnd = PropertyUtil.CreateAreaDensityPropertyFromElement(file, exporterIFC, element, revitParamNameToUse, - builtInParameter, ifcPropertyName, valueType); + propHnd = PropertyUtil.CreateAreaDensityPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.Boolean: @@ -468,13 +468,13 @@ private static IFCData GetPropertyDataFromString(string valueString, PropertyTyp case PropertyType.ClassificationReference: { propHnd = PropertyUtil.CreateClassificationReferencePropertyFromElement(file, exporterIFC, element, revitParamNameToUse, - builtInParameter, ifcPropertyName); + builtInParameter, ifcPropertyName); break; } case PropertyType.ColorTemperature: { - propHnd = PropertyUtil.CreateColorTemperaturePropertyFromElement(file, exporterIFC, element, revitParamNameToUse, builtInParameter, - ifcPropertyName, valueType); + propHnd = PropertyUtil.CreateUserDefinedRealPropertyFromElement(file, element, revitParamNameToUse, builtInParameter, + ifcPropertyName, valueType, SpecTypeId.ColorTemperature, "COLORTEMPERATURE"); break; } case PropertyType.Count: @@ -485,77 +485,62 @@ private static IFCData GetPropertyDataFromString(string valueString, PropertyTyp } case PropertyType.Currency: { - propHnd = PropertyUtil.CreateCurrencyPropertyFromElement(file, exporterIFC, element, revitParamNameToUse, builtInParameter, - ifcPropertyName, valueType); + propHnd = PropertyUtil.CreateCurrencyPropertyFromElement(file, exporterIFC, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.DynamicViscosity: { - propHnd = PropertyUtil.CreateDynamicViscosityPropertyFromElement(file, exporterIFC, element, revitParamNameToUse, + propHnd = PropertyUtil.CreateDynamicViscosityPropertyFromElement(file, element, revitParamNameToUse, builtInParameter, ifcPropertyName, valueType); break; } - case PropertyType.ElectricalEfficacy: - { - propHnd = PropertyUtil.CreateElectricalEfficacyPropertyFromElement(file, exporterIFC, element, revitParamNameToUse, builtInParameter, - ifcPropertyName, valueType); - break; - } - case PropertyType.ElectricalResistivity: - { - propHnd = PropertyUtil.CreateElectricalResistivityPropertyFromElement(file, exporterIFC, element, revitParamNameToUse, builtInParameter, - ifcPropertyName, valueType); - break; - } case PropertyType.ElectricCurrent: { - propHnd = ElectricalCurrentPropertyUtil.CreateElectricalCurrentMeasurePropertyFromElement(file, element, revitParamNameToUse, ifcPropertyName, valueType); + propHnd = PropertyUtil.CreateElectricCurrentPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.ElectricVoltage: { - propHnd = ElectricVoltagePropertyUtil.CreateElectricVoltageMeasurePropertyFromElement(file, element, revitParamNameToUse, ifcPropertyName, valueType); + propHnd = PropertyUtil.CreateElectricVoltagePropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.Energy: { - propHnd = PropertyUtil.CreateEnergyMeasurePropertyFromElement(file, exporterIFC, element, revitParamNameToUse, + propHnd = PropertyUtil.CreateEnergyPropertyFromElement(file, element, revitParamNameToUse, builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.Force: { - propHnd = FrequencyPropertyUtil.CreateForcePropertyFromElement(file, exporterIFC, element, revitParamNameToUse, builtInParameter, - ifcPropertyName, valueType); + propHnd = PropertyUtil.CreateForcePropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.Frequency: { - propHnd = FrequencyPropertyUtil.CreateFrequencyPropertyFromElement(file, exporterIFC, element, revitParamNameToUse, builtInParameter, - ifcPropertyName, valueType); - break; - } - case PropertyType.FrictionLoss: - { - propHnd = PropertyUtil.CreateFrictionLossPropertyFromElement(file, exporterIFC, element, revitParamNameToUse, builtInParameter, - ifcPropertyName, valueType); + propHnd = PropertyUtil.CreateFrequencyPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.HeatingValue: { - propHnd = PropertyUtil.CreateHeatingValuePropertyFromElement(file, exporterIFC, element, revitParamNameToUse, builtInParameter, - ifcPropertyName, valueType); + propHnd = PropertyUtil.CreateHeatingValuePropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.Identifier: { - propHnd = PropertyUtil.CreateIdentifierPropertyFromElement(file, element, revitParamNameToUse, builtInParameter, ifcPropertyName, valueType); + propHnd = PropertyUtil.CreateIdentifierPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.Illuminance: { - propHnd = PropertyUtil.CreateIlluminancePropertyFromElement(file, exporterIFC, element, revitParamNameToUse, builtInParameter, - ifcPropertyName, valueType); + propHnd = PropertyUtil.CreateIlluminancePropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.Integer: @@ -565,55 +550,56 @@ private static IFCData GetPropertyDataFromString(string valueString, PropertyTyp } case PropertyType.IonConcentration: { - propHnd = PropertyUtil.CreateIonConcentrationPropertyFromElement(file, exporterIFC, element, revitParamNameToUse, builtInParameter, - ifcPropertyName, valueType); + propHnd = PropertyUtil.CreateIonConcentrationPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.IsothermalMoistureCapacity: { - propHnd = PropertyUtil.CreateIsothermalMoistureCapacityPropertyFromElement(file, exporterIFC, element, revitParamNameToUse, builtInParameter, - ifcPropertyName, valueType); + propHnd = PropertyUtil.CreateIsothermalMoistureCapacityPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.HeatFluxDensity: { - propHnd = PropertyUtil.CreateHeatFluxDensityPropertyFromElement(file, exporterIFC, element, revitParamNameToUse, builtInParameter, - ifcPropertyName, valueType); + propHnd = PropertyUtil.CreateHeatFluxDensityPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.Label: { - propHnd = PropertyUtil.CreateLabelPropertyFromElement(file, element, revitParamNameToUse, builtInParameter, ifcPropertyName, valueType, propertyEnumerationType); + propHnd = PropertyUtil.CreateLabelPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType, propertyEnumerationType); break; } case PropertyType.Length: { - propHnd = PropertyUtil.CreateLengthMeasurePropertyFromElement(file, exporterIFC, element, revitParamNameToUse, + propHnd = PropertyUtil.CreateLengthPropertyFromElement(file, element, revitParamNameToUse, builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.LinearForce: { - propHnd = PropertyUtil.CreateLinearForcePropertyFromElement(file, exporterIFC, element, revitParamNameToUse, builtInParameter, - ifcPropertyName, valueType); + propHnd = PropertyUtil.CreateLinearForcePropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.LinearMoment: { - propHnd = PropertyUtil.CreateLinearMomentMeasurePropertyFromElement(file, exporterIFC, element, revitParamNameToUse, + propHnd = PropertyUtil.CreateLinearMomentPropertyFromElement(file, element, revitParamNameToUse, builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.LinearStiffness: { - propHnd = PropertyUtil.CreateLinearStiffnessMeasurePropertyFromElement(file, exporterIFC, element, revitParamNameToUse, + propHnd = PropertyUtil.CreateLinearStiffnessPropertyFromElement(file, element, revitParamNameToUse, builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.LinearVelocity: { - propHnd = PropertyUtil.CreateLinearVelocityPropertyFromElement(file, exporterIFC, element, revitParamNameToUse, - ifcPropertyName, valueType); + propHnd = PropertyUtil.CreateLinearVelocityPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.Logical: @@ -623,217 +609,412 @@ private static IFCData GetPropertyDataFromString(string valueString, PropertyTyp } case PropertyType.LuminousFlux: { - propHnd = PropertyUtil.CreateLuminousFluxMeasurePropertyFromElement(file, exporterIFC, element, revitParamNameToUse, + propHnd = PropertyUtil.CreateLuminousFluxPropertyFromElement(file, element, revitParamNameToUse, builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.LuminousIntensity: { - propHnd = PropertyUtil.CreateLuminousIntensityPropertyFromElement(file, exporterIFC, element, revitParamNameToUse, builtInParameter, - ifcPropertyName, valueType); + propHnd = PropertyUtil.CreateLuminousIntensityPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.Mass: { - propHnd = PropertyUtil.CreateMassPropertyFromElement(file, exporterIFC, element, revitParamNameToUse, builtInParameter, - ifcPropertyName, valueType); + propHnd = PropertyUtil.CreateMassPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.MassDensity: { - propHnd = PropertyUtil.CreateMassDensityPropertyFromElement(file, exporterIFC, element, revitParamNameToUse, builtInParameter, - ifcPropertyName, valueType); + propHnd = PropertyUtil.CreateMassDensityPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.MassFlowRate: { - propHnd = PropertyUtil.CreateMassFlowRatePropertyFromElement(file, exporterIFC, element, revitParamNameToUse, builtInParameter, - ifcPropertyName, valueType); + propHnd = PropertyUtil.CreateMassFlowRatePropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.MassPerLength: { - propHnd = PropertyUtil.CreateMassPerLengthMeasurePropertyFromElement(file, exporterIFC, element, revitParamNameToUse, + propHnd = PropertyUtil.CreateMassPerLengthPropertyFromElement(file, element, revitParamNameToUse, builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.ModulusOfElasticity: { - propHnd = PropertyUtil.CreateModulusOfElasticityPropertyFromElement(file, exporterIFC, element, revitParamNameToUse, builtInParameter, - ifcPropertyName, valueType); + propHnd = PropertyUtil.CreateModulusOfElasticityPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.MoistureDiffusivity: { - propHnd = PropertyUtil.CreateMoistureDiffusivityPropertyFromElement(file, exporterIFC, element, revitParamNameToUse, builtInParameter, - ifcPropertyName, valueType); + propHnd = PropertyUtil.CreateMoistureDiffusivityPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.MomentOfInertia: { - propHnd = PropertyUtil.CreateMomentOfInertiaPropertyFromElement(file, exporterIFC, element, revitParamNameToUse, builtInParameter, - ifcPropertyName, valueType); + propHnd = PropertyUtil.CreateMomentOfInertiaPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.NormalisedRatio: { - propHnd = PropertyUtil.CreateNormalisedRatioPropertyFromElement(file, exporterIFC, element, revitParamNameToUse, - ifcPropertyName, valueType); + propHnd = PropertyUtil.CreateNormalisedRatioPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.Numeric: { - propHnd = PropertyUtil.CreateNumericPropertyFromElement(file, element, revitParamNameToUse, ifcPropertyName, valueType); + propHnd = PropertyUtil.CreateNumericPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.PlaneAngle: { - propHnd = PropertyUtil.CreatePlaneAngleMeasurePropertyFromElement(file, element, revitParamNameToUse, ifcPropertyName, - valueType); + propHnd = PropertyUtil.CreatePlaneAnglePropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.PlanarForce: { - propHnd = PropertyUtil.CreatePlanarForcePropertyFromElement(file, exporterIFC, element, revitParamNameToUse, builtInParameter, - ifcPropertyName, valueType); + propHnd = PropertyUtil.CreatePlanarForcePropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.PositiveLength: { - propHnd = PropertyUtil.CreatePositiveLengthMeasurePropertyFromElement(file, exporterIFC, element, revitParamNameToUse, + propHnd = PropertyUtil.CreatePositiveLengthPropertyFromElement(file, element, revitParamNameToUse, builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.PositiveRatio: { - propHnd = PropertyUtil.CreatePositiveRatioPropertyFromElement(file, exporterIFC, element, revitParamNameToUse, - ifcPropertyName, valueType); + propHnd = PropertyUtil.CreatePositiveRatioPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.PositivePlaneAngle: { - propHnd = PositivePlaneAnglePropertyUtil.CreatePositivePlaneAngleMeasurePropertyFromElement(file, element, revitParamNameToUse, ifcPropertyName, - valueType); + propHnd = PropertyUtil.CreatePositivePlaneAnglePropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.Power: { - propHnd = PropertyUtil.CreatePowerPropertyFromElement(file, exporterIFC, element, revitParamNameToUse, builtInParameter, - ifcPropertyName, valueType); + propHnd = PropertyUtil.CreatePowerPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.Pressure: { - propHnd = FrequencyPropertyUtil.CreatePressurePropertyFromElement(file, exporterIFC, element, revitParamNameToUse, builtInParameter, - ifcPropertyName, valueType); + propHnd = PropertyUtil.CreatePressurePropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.Ratio: { - propHnd = PropertyUtil.CreateRatioPropertyFromElement(file, exporterIFC, element, revitParamNameToUse, ifcPropertyName, - valueType); + propHnd = PropertyUtil.CreateRatioPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.Real: { - propHnd = PropertyUtil.CreateRealPropertyFromElement(file, element, revitParamNameToUse, ifcPropertyName, valueType); + propHnd = PropertyUtil.CreateRealPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.RotationalFrequency: { - propHnd = PropertyUtil.CreateRotationalFrequencyPropertyFromElement(file, exporterIFC, element, revitParamNameToUse, builtInParameter, - ifcPropertyName, valueType); + propHnd = PropertyUtil.CreateRotationalFrequencyPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.SoundPower: { - propHnd = PropertyUtil.CreateSoundPowerPropertyFromElement(file, exporterIFC, element, revitParamNameToUse, + propHnd = PropertyUtil.CreateSoundPowerPropertyFromElement(file, element, revitParamNameToUse, builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.SoundPressure: { - propHnd = PropertyUtil.CreateSoundPressurePropertyFromElement(file, exporterIFC, element, revitParamNameToUse, + propHnd = PropertyUtil.CreateSoundPressurePropertyFromElement(file, element, revitParamNameToUse, builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.SpecificHeatCapacity: { - propHnd = PropertyUtil.CreateSpecificHeatCapacityPropertyFromElement(file, exporterIFC, element, revitParamNameToUse, + propHnd = PropertyUtil.CreateSpecificHeatCapacityPropertyFromElement(file, element, revitParamNameToUse, builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.Text: { - propHnd = PropertyUtil.CreateTextPropertyFromElement(file, element, revitParamNameToUse, builtInParameter, ifcPropertyName, valueType, propertyEnumerationType); + propHnd = PropertyUtil.CreateTextPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType, propertyEnumerationType); break; } case PropertyType.ThermalConductivity: { - propHnd = PropertyUtil.CreateThermalConductivityPropertyFromElement(file, exporterIFC, element, revitParamNameToUse, + propHnd = PropertyUtil.CreateThermalConductivityPropertyFromElement(file, element, revitParamNameToUse, builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.ThermalExpansionCoefficient: { - propHnd = PropertyUtil.CreateThermalExpansionCoefficientPropertyFromElement(file, exporterIFC, element, revitParamNameToUse, + propHnd = PropertyUtil.CreateThermalExpansionCoefficientPropertyFromElement(file, element, revitParamNameToUse, builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.ThermalResistance: { - propHnd = PropertyUtil.CreateThermalResistanceMeasurePropertyFromElement(file, exporterIFC, element, revitParamNameToUse, + propHnd = PropertyUtil.CreateThermalResistancePropertyFromElement(file, element, revitParamNameToUse, builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.ThermalTransmittance: { - propHnd = PropertyUtil.CreateThermalTransmittancePropertyFromElement(file, exporterIFC, element, revitParamNameToUse, + propHnd = PropertyUtil.CreateThermalTransmittancePropertyFromElement(file, element, revitParamNameToUse, builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.ThermodynamicTemperature: { - propHnd = PropertyUtil.CreateThermodynamicTemperaturePropertyFromElement(file, exporterIFC, element, revitParamNameToUse, + propHnd = PropertyUtil.CreateThermodynamicTemperaturePropertyFromElement(file, element, revitParamNameToUse, builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.VaporPermeability: { - propHnd = PropertyUtil.CreateVaporPermeabilityMeasurePropertyFromElement(file, exporterIFC, element, revitParamNameToUse, + propHnd = PropertyUtil.CreateVaporPermeabilityPropertyFromElement(file, element, revitParamNameToUse, builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.Volume: { - propHnd = PropertyUtil.CreateVolumeMeasurePropertyFromElement(file, exporterIFC, element, revitParamNameToUse, + propHnd = PropertyUtil.CreateVolumePropertyFromElement(file, element, revitParamNameToUse, builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.VolumetricFlowRate: { - propHnd = PropertyUtil.CreateVolumetricFlowRatePropertyFromElement(file, exporterIFC, element, revitParamNameToUse, + propHnd = PropertyUtil.CreateVolumetricFlowRatePropertyFromElement(file, element, revitParamNameToUse, builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.Time: { - propHnd = PropertyUtil.CreateTimePropertyFromElement(file, exporterIFC, element, revitParamNameToUse, + propHnd = PropertyUtil.CreateTimePropertyFromElement(file, element, revitParamNameToUse, builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.Torque: { - propHnd = PropertyUtil.CreateTorqueMeasurePropertyFromElement(file, exporterIFC, element, revitParamNameToUse, + propHnd = PropertyUtil.CreateTorquePropertyFromElement(file, element, revitParamNameToUse, builtInParameter, ifcPropertyName, valueType); break; } case PropertyType.WarpingConstant: { - propHnd = PropertyUtil.CreateWarpingConstantMeasurePropertyFromElement(file, exporterIFC, element, revitParamNameToUse, + propHnd = PropertyUtil.CreateWarpingConstantPropertyFromElement(file, element, revitParamNameToUse, builtInParameter, ifcPropertyName, valueType); break; } + case PropertyType.CostPerArea: + { + propHnd = PropertyUtil.CreateUserDefinedRealPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType, SpecTypeId.CostPerArea, "COSTPERAREA"); + break; + } + case PropertyType.ApparentPowerDensity: + { + propHnd = PropertyUtil.CreateUserDefinedRealPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType, SpecTypeId.ApparentPowerDensity, "APPARENTPOWERDENSITY"); + break; + } + case PropertyType.CostRateEnergy: + { + propHnd = PropertyUtil.CreateUserDefinedRealPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType, SpecTypeId.CostRateEnergy, "COSTRATEENERGY"); + break; + } + case PropertyType.CostRatePower: + { + propHnd = PropertyUtil.CreateUserDefinedRealPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType, SpecTypeId.CostRatePower, "COSTRATEPOWER"); + break; + } + case PropertyType.ElectricalEfficacy: + { + propHnd = PropertyUtil.CreateUserDefinedRealPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType, SpecTypeId.Efficacy, "LUMINOUSEFFICACY"); + break; + } + case PropertyType.Luminance: + { + propHnd = PropertyUtil.CreateUserDefinedRealPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType, SpecTypeId.Luminance, "LUMINANCE"); + break; + } + case PropertyType.ElectricalPowerDensity: + { + propHnd = PropertyUtil.CreateUserDefinedRealPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType, SpecTypeId.ElectricalPowerDensity, "ELECTRICALPOWERDENSITY"); + break; + } + case PropertyType.PowerPerLength: + { + propHnd = PropertyUtil.CreateUserDefinedRealPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType, SpecTypeId.PowerPerLength, "POWERPERLENGTH"); + break; + } + case PropertyType.ElectricalResistivity: + { + propHnd = PropertyUtil.CreateUserDefinedRealPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType, SpecTypeId.ElectricalResistivity, "ELECTRICALRESISTIVITY"); + break; + } + case PropertyType.HeatCapacityPerArea: + { + propHnd = PropertyUtil.CreateUserDefinedRealPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType, SpecTypeId.HeatCapacityPerArea, "HEATCAPACITYPERAREA"); + break; + } + case PropertyType.ThermalGradientCoefficientForMoistureCapacity: + { + propHnd = PropertyUtil.CreateUserDefinedRealPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType, SpecTypeId.ThermalGradientCoefficientForMoistureCapacity, "THERMALGRADIENTCOEFFICIENTFORMOISTURECAPACITY"); + break; + } + case PropertyType.ThermalMass: + { + propHnd = PropertyUtil.CreateUserDefinedRealPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType, SpecTypeId.ThermalMass, "THERMALMASS"); + break; + } + case PropertyType.AirFlowDensity: + { + propHnd = PropertyUtil.CreateUserDefinedRealPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType, SpecTypeId.AirFlowDensity, "AIRFLOWDENSITY"); + break; + } + case PropertyType.AirFlowDividedByCoolingLoad: + { + propHnd = PropertyUtil.CreateUserDefinedRealPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType, SpecTypeId.AirFlowDividedByCoolingLoad, "AIRFLOWDIVIDEDBYCOOLINGLOAD"); + break; + } + case PropertyType.AirFlowDividedByVolume: + { + propHnd = PropertyUtil.CreateUserDefinedRealPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType, SpecTypeId.AirFlowDividedByVolume, "AIRFLOWDIVIDEDBYVOLUME"); + break; + } + case PropertyType.AreaDividedByCoolingLoad: + { + propHnd = PropertyUtil.CreateUserDefinedRealPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType, SpecTypeId.AreaDividedByCoolingLoad, "AREADIVIDEDBYCOOLINGLOAD"); + break; + } + case PropertyType.AreaDividedByHeatingLoad: + { + propHnd = PropertyUtil.CreateUserDefinedRealPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType, SpecTypeId.AreaDividedByHeatingLoad, "AREADIVIDEDBYHEATINGLOAD"); + break; + } + case PropertyType.CoolingLoadDividedByArea: + { + propHnd = PropertyUtil.CreateUserDefinedRealPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType, SpecTypeId.CoolingLoadDividedByArea, "COOLINGLOADDIVIDEDBYAREA"); + break; + } + case PropertyType.CoolingLoadDividedByVolume: + { + propHnd = PropertyUtil.CreateUserDefinedRealPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType, SpecTypeId.CoolingLoadDividedByVolume, "COOLINGLOADDIVIDEDBYVOLUME"); + break; + } + case PropertyType.FlowPerPower: + { + propHnd = PropertyUtil.CreateUserDefinedRealPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType, SpecTypeId.FlowPerPower, "FLOWPERPOWER"); + break; + } + case PropertyType.FrictionLoss: + { + propHnd = PropertyUtil.CreateUserDefinedRealPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType, SpecTypeId.HvacFriction, "FRICTIONLOSS"); + break; + } + case PropertyType.HeatingLoadDividedByArea: + { + propHnd = PropertyUtil.CreateUserDefinedRealPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType, SpecTypeId.HeatingLoadDividedByArea, "HEATINGLOADDIVIDEDBYAREA"); + break; + } + case PropertyType.HeatingLoadDividedByVolume: + { + propHnd = PropertyUtil.CreateUserDefinedRealPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType, SpecTypeId.HeatingLoadDividedByVolume, "HEATINGLOADDIVIDEDBYVOLUME"); + break; + } + case PropertyType.PowerPerFlow: + { + propHnd = PropertyUtil.CreateUserDefinedRealPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType, SpecTypeId.PowerPerFlow, "POWERPERFLOW"); + break; + } + case PropertyType.PipingFriction: + { + propHnd = PropertyUtil.CreateUserDefinedRealPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType, SpecTypeId.PipingFriction, "PIPINGFRICTION"); + break; + } + case PropertyType.AreaSpringCoefficient: + { + propHnd = PropertyUtil.CreateUserDefinedRealPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType, SpecTypeId.AreaSpringCoefficient, "AREASPRINGCOEFFICIENT"); + break; + } + case PropertyType.LineSpringCoefficient: + { + propHnd = PropertyUtil.CreateUserDefinedRealPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType, SpecTypeId.LineSpringCoefficient, "LINESPRINGCOEFFICIENT"); + break; + } + case PropertyType.MassPerUnitArea: + { + propHnd = PropertyUtil.CreateUserDefinedRealPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType, SpecTypeId.MassPerUnitArea, "MASSPERUNITAREA"); + break; + } + case PropertyType.ReinforcementAreaPerUnitLength: + { + propHnd = PropertyUtil.CreateUserDefinedRealPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType, SpecTypeId.ReinforcementAreaPerUnitLength, "REINFORCEMENTAREAPERUNITLENGTH"); + break; + } + case PropertyType.RotationalLineSpringCoefficient: + { + propHnd = PropertyUtil.CreateUserDefinedRealPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType, SpecTypeId.RotationalLineSpringCoefficient, "ROTATIONALLINESPRINGCOEFFICIENT"); + break; + } + case PropertyType.RotationalPointSpringCoefficient: + { + propHnd = PropertyUtil.CreateUserDefinedRealPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType, SpecTypeId.RotationalPointSpringCoefficient, "ROTATIONALPOINTSPRINGCOEFFICIENT"); + break; + } + case PropertyType.UnitWeight: + { + propHnd = PropertyUtil.CreateUserDefinedRealPropertyFromElement(file, element, revitParamNameToUse, + builtInParameter, ifcPropertyName, valueType, SpecTypeId.UnitWeight, "UNITWEIGHT"); + break; + } // Known unhandled cases: case PropertyType.IfcCalendarDate: case PropertyType.IfcClassificationReference: @@ -1095,61 +1276,61 @@ private static IFCData GetPropertyDataFromString(string valueString, PropertyTyp case PropertyType.Real: { double val = (useCalculator) ? PropertyCalculator.GetDoubleValue() : double.Parse(propertyValue); - propHnd = PropertyUtil.CreateRealPropertyFromCache(file, propertyName, val, valueType); + propHnd = PropertyUtil.CreateRealPropertyFromCache(file, propertyName, new List() { val }, valueType, null); break; } case PropertyType.Length: { double val = (useCalculator) ? PropertyCalculator.GetDoubleValue() : double.Parse(propertyValue); - propHnd = PropertyUtil.CreateLengthMeasurePropertyFromCache(file, propertyName, val, valueType); + propHnd = PropertyUtil.CreateLengthPropertyFromCache(file, propertyName, new List() { val }, valueType, null); break; } case PropertyType.PositiveLength: { double val = (useCalculator) ? PropertyCalculator.GetDoubleValue() : double.Parse(propertyValue); - propHnd = PropertyUtil.CreatePositiveLengthMeasureProperty(file, propertyName, val, valueType); + propHnd = PropertyUtil.CreatePositiveLengthProperty(file, propertyName, new List() { val }, valueType, null); break; } case PropertyType.NormalisedRatio: { double val = (useCalculator) ? PropertyCalculator.GetDoubleValue() : double.Parse(propertyValue); - propHnd = PropertyUtil.CreateNormalisedRatioMeasureProperty(file, propertyName, val, valueType); + propHnd = PropertyUtil.CreateNormalisedRatioProperty(file, propertyName, new List() { val }, valueType, null); break; } case PropertyType.Numeric: { double val = (useCalculator) ? PropertyCalculator.GetDoubleValue() : double.Parse(propertyValue); - propHnd = PropertyUtil.CreateNumericPropertyFromCache(file, propertyName, val, valueType); + propHnd = PropertyUtil.CreateNumericPropertyFromCache(file, propertyName, new List() { val }, valueType, null); break; } case PropertyType.PositiveRatio: { double val = (useCalculator) ? PropertyCalculator.GetDoubleValue() : double.Parse(propertyValue); - propHnd = PropertyUtil.CreatePositiveRatioMeasureProperty(file, propertyName, val, valueType); + propHnd = PropertyUtil.CreatePositiveRatioProperty(file, propertyName, new List() { val }, valueType, null); break; } case PropertyType.Ratio: { double val = (useCalculator) ? PropertyCalculator.GetDoubleValue() : double.Parse(propertyValue); - propHnd = PropertyUtil.CreateRatioMeasureProperty(file, propertyName, val, valueType); + propHnd = PropertyUtil.CreateRatioProperty(file, propertyName, new List() { val }, valueType, null); break; } case PropertyType.PlaneAngle: { double val = (useCalculator) ? PropertyCalculator.GetDoubleValue() : double.Parse(propertyValue); - propHnd = PropertyUtil.CreatePlaneAngleMeasurePropertyFromCache(file, propertyName, val, valueType); + propHnd = PropertyUtil.CreatePlaneAnglePropertyFromCache(file, propertyName, new List() { val }, valueType, null); break; } case PropertyType.PositivePlaneAngle: { double val = (useCalculator) ? PropertyCalculator.GetDoubleValue() : double.Parse(propertyValue); - propHnd = PositivePlaneAnglePropertyUtil.CreatePositivePlaneAngleMeasurePropertyFromCache(file, propertyName, val, valueType); + propHnd = PropertyUtil.CreatePositivePlaneAnglePropertyFromCache(file, propertyName, new List() { val }, valueType, null); break; } case PropertyType.Area: { double val = (useCalculator) ? PropertyCalculator.GetDoubleValue() : double.Parse(propertyValue); - propHnd = PropertyUtil.CreateAreaMeasureProperty(file, propertyName, val, valueType); + propHnd = PropertyUtil.CreateAreaProperty(file, propertyName, new List() { val }, valueType, null); break; } case PropertyType.Count: @@ -1169,37 +1350,37 @@ private static IFCData GetPropertyDataFromString(string valueString, PropertyTyp case PropertyType.Frequency: { double val = (useCalculator) ? PropertyCalculator.GetDoubleValue() : double.Parse(propertyValue); - propHnd = FrequencyPropertyUtil.CreateFrequencyProperty(file, propertyName, val, valueType); + propHnd = PropertyUtil.CreateFrequencyProperty(file, propertyName, new List() { val }, valueType, null); break; } case PropertyType.Power: { double val = (useCalculator) ? PropertyCalculator.GetDoubleValue() : double.Parse(propertyValue); - propHnd = PropertyUtil.CreatePowerPropertyFromCache(file, propertyName, val, valueType); + propHnd = PropertyUtil.CreatePowerPropertyFromCache(file, propertyName, new List() { val }, valueType, null); break; } case PropertyType.ThermodynamicTemperature: { double val = (useCalculator) ? PropertyCalculator.GetDoubleValue() : double.Parse(propertyValue); - propHnd = PropertyUtil.CreateThermodynamicTemperaturePropertyFromCache(file, propertyName, val, valueType); + propHnd = PropertyUtil.CreateThermodynamicTemperaturePropertyFromCache(file, propertyName, new List() { val }, valueType, null); break; } case PropertyType.ThermalTransmittance: { double val = (useCalculator) ? PropertyCalculator.GetDoubleValue() : double.Parse(propertyValue); - propHnd = PropertyUtil.CreateThermalTransmittancePropertyFromCache(file, propertyName, val, valueType); + propHnd = PropertyUtil.CreateThermalTransmittancePropertyFromCache(file, propertyName, new List() { val }, valueType, null); break; } case PropertyType.VolumetricFlowRate: { double val = (useCalculator) ? PropertyCalculator.GetDoubleValue() : double.Parse(propertyValue); - propHnd = PropertyUtil.CreateVolumetricFlowRateMeasureProperty(file, propertyName, val, valueType); + propHnd = PropertyUtil.CreateVolumetricFlowRateProperty(file, propertyName, new List() { val }, valueType, null); break; } case PropertyType.LinearVelocity: { double val = (useCalculator) ? PropertyCalculator.GetDoubleValue() : double.Parse(propertyValue); - propHnd = PropertyUtil.CreateLinearVelocityMeasureProperty(file, propertyName, val, valueType); + propHnd = PropertyUtil.CreateLinearVelocityProperty(file, propertyName, new List() { val }, valueType, null); break; } default: diff --git a/Source/Revit.IFC.Export/Exporter/PropertySet/PropertyUtil.cs b/Source/Revit.IFC.Export/Exporter/PropertySet/PropertyUtil.cs index 1bb85224..694cf281 100644 --- a/Source/Revit.IFC.Export/Exporter/PropertySet/PropertyUtil.cs +++ b/Source/Revit.IFC.Export/Exporter/PropertySet/PropertyUtil.cs @@ -27,6 +27,7 @@ using Revit.IFC.Export.Toolkit; using System.ComponentModel; using System.Linq; +using System.Collections; namespace Revit.IFC.Export.Exporter.PropertySet { @@ -61,39 +62,34 @@ public static ISet EntitiesWithNoRelatedType } } - - - public static IFCAnyHandle CreateCommonProperty(IFCFile file, string propertyName, IFCData valueData, PropertyValueType valueType, string unitTypeKey) + public static IFCAnyHandle CreateCommonPropertyFromList(IFCFile file, string propertyName, IList valueList, PropertyValueType valueType, string unitTypeKey) { - IFCAnyHandle unitHnd = (!ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView && unitTypeKey != null) ? ExporterCacheManager.UnitsCache[unitTypeKey] : null; + if (valueList == null || valueList.All(x => x == null)) + return null; + + IFCAnyHandle unitHnd = (!ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView && unitTypeKey != null) ? ExporterCacheManager.UnitsCache.FindUserDefinedUnit(unitTypeKey) : null; switch (valueType) { case PropertyValueType.EnumeratedValue: { - IList valueList = new List(); - valueList.Add(valueData); return IFCInstanceExporter.CreatePropertyEnumeratedValue(file, propertyName, null, valueList, null); } case PropertyValueType.SingleValue: { - return IFCInstanceExporter.CreatePropertySingleValue(file, propertyName, null, valueData, unitHnd); + return IFCInstanceExporter.CreatePropertySingleValue(file, propertyName, null, valueList.First(), unitHnd); } case PropertyValueType.ListValue: { - IList valueList = new List(); - valueList.Add(valueData); return IFCInstanceExporter.CreatePropertyListValue(file, propertyName, null, valueList, unitHnd); } case PropertyValueType.BoundedValue: { - IList valueList = new List(); - valueList.Add(valueData); return CreateBoundedValuePropertyFromList(file, propertyName, valueList, unitTypeKey); } case PropertyValueType.TableValue: { - // must be handled in CreatePropertyFromElementBase + // for now is handled in CreatePropertyFromElementBase as Multiline Text throw new InvalidOperationException("Unhandled table property!"); } default: @@ -101,6 +97,11 @@ public static IFCAnyHandle CreateCommonProperty(IFCFile file, string propertyNam } } + public static IFCAnyHandle CreateCommonProperty(IFCFile file, string propertyName, IFCData valueData, PropertyValueType valueType, string unitTypeKey) + { + return CreateCommonPropertyFromList(file, propertyName, new List() { valueData }, valueType, unitTypeKey); + } + /// /// Creates an IfcPropertyBoundedValue. /// @@ -112,7 +113,7 @@ protected static IFCAnyHandle CreateBoundedValuePropertyFromList(IFCFile file, s { if (valueDataList.Count < 1) throw new InvalidOperationException("Invalid bounded property!"); - IFCAnyHandle unitHnd = (!ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView && unitTypeKey != null) ? ExporterCacheManager.UnitsCache[unitTypeKey] : null; + IFCAnyHandle unitHnd = (!ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView && unitTypeKey != null) ? ExporterCacheManager.UnitsCache.FindUserDefinedUnit(unitTypeKey) : null; IFCData setPointValue = valueDataList[0]; IFCData upperBoundValue = valueDataList.Count > 1 ? valueDataList[1] : null; @@ -125,7 +126,7 @@ protected static IFCAnyHandle CreateBoundedValuePropertyFromList(IFCFile file, s else { return IFCInstanceExporter.CreatePropertyBoundedValue(file, propertyName, null, lowerBoundValue, upperBoundValue, setPointValue, unitHnd); - } + } } /// @@ -140,8 +141,8 @@ protected static IFCAnyHandle CreateBoundedValuePropertyFromList(IFCFile file, s /// The created property handle. public static IFCAnyHandle CreateTableProperty(IFCFile file, string propertyName, IList definingValues, IList definedValues, string definingUnitTypeKey, string definedUnitTypeKey) { - IFCAnyHandle definingUnitHnd = (!ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView && definingUnitTypeKey != null) ? ExporterCacheManager.UnitsCache[definingUnitTypeKey] : null; - IFCAnyHandle definedUnitHnd = (!ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView && definedUnitTypeKey != null) ? ExporterCacheManager.UnitsCache[definedUnitTypeKey] : null; + IFCAnyHandle definingUnitHnd = (!ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView && definingUnitTypeKey != null) ? ExporterCacheManager.UnitsCache.FindUserDefinedUnit(definingUnitTypeKey) : null; + IFCAnyHandle definedUnitHnd = (!ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView && definedUnitTypeKey != null) ? ExporterCacheManager.UnitsCache.FindUserDefinedUnit(definedUnitTypeKey) : null; return IFCInstanceExporter.CreatePropertyTableValue(file, propertyName, null, definingValues, definedValues, definingUnitHnd, definedUnitHnd); } @@ -151,7 +152,7 @@ public static IFCAnyHandle CreateTableProperty(IFCFile file, string propertyName /// /// The IFC file. /// The name of the property. - /// The value of the property. + /// The values of the property. /// The value type of the property. /// The created property handle. public static IFCAnyHandle CreateLabelProperty(IFCFile file, string propertyName, string value, PropertyValueType valueType, @@ -208,7 +209,7 @@ public static IFCAnyHandle CreateTableProperty(IFCFile file, string propertyName /// /// The IFC file. /// The name of the property. - /// The value of the property. + /// The values of the property. /// The value type of the property. /// The created property handle. public static IFCAnyHandle CreateTextProperty(IFCFile file, string propertyName, string value, PropertyValueType valueType) @@ -222,7 +223,7 @@ public static IFCAnyHandle CreateTextProperty(IFCFile file, string propertyName, /// /// The IFC file. /// The name of the property. - /// The value of the property. + /// The values of the property. /// The value type of the property. /// The created property handle. public static IFCAnyHandle CreateTextPropertyFromCache(IFCFile file, string propertyName, string value, PropertyValueType valueType) @@ -306,7 +307,7 @@ public static IFCAnyHandle CreateTextPropertyFromElement(IFCFile file, Element e /// The IFC file. /// The id of the parameter that generated the value. /// The name of the property. - /// The value of the property. + /// The values of the property. /// The value type of the property. /// Whether to cache all strings (true), or only the empty string (false). /// The type of the enum, null if valueType isn't EnumeratedValue. @@ -376,7 +377,7 @@ public static IFCAnyHandle CreateTextPropertyFromElement(IFCFile file, Element e /// /// The IFC file. /// The name of the property. - /// The value of the property. + /// The values of the property. /// The value type of the property. /// The created property handle. public static IFCAnyHandle CreateIdentifierProperty(IFCFile file, string propertyName, string value, PropertyValueType valueType) @@ -390,7 +391,7 @@ public static IFCAnyHandle CreateIdentifierProperty(IFCFile file, string propert /// /// The IFC file. /// The name of the property. - /// The value of the property. + /// The values of the property. /// The value type of the property. /// The created property handle. public static IFCAnyHandle CreateIdentifierPropertyFromCache(IFCFile file, string propertyName, string value, PropertyValueType valueType) @@ -411,7 +412,7 @@ public static IFCAnyHandle CreateIdentifierPropertyFromCache(IFCFile file, strin /// /// The IFC file. /// The name of the property. - /// The value of the property. + /// The values of the property. /// The value type of the property. /// The created property handle. public static IFCAnyHandle CreateBooleanProperty(IFCFile file, string propertyName, bool value, PropertyValueType valueType) @@ -425,7 +426,7 @@ public static IFCAnyHandle CreateBooleanProperty(IFCFile file, string propertyNa /// /// The IFC file. /// The name of the property. - /// The value of the property. + /// The values of the property. /// The value type of the property. /// The created property handle. public static IFCAnyHandle CreateLogicalProperty(IFCFile file, string propertyName, IFCLogical value, PropertyValueType valueType) @@ -479,7 +480,7 @@ public static IFCAnyHandle CreateLogicalPropertyFromCache(IFCFile file, string p /// /// The IFC file. /// The name of the property. - /// The value of the property. + /// The values of the property. /// The value type of the property. /// The created property handle. public static IFCAnyHandle CreateIntegerProperty(IFCFile file, string propertyName, int value, PropertyValueType valueType) @@ -519,2433 +520,1980 @@ public static IFCAnyHandle CreateIntegerPropertyFromCache(IFCFile file, string p internal static double? CanCacheDouble(double value) { - // We have a partial cache here - cache multiples of 0.5 up to 10. - if (MathUtil.IsAlmostZero(value)) - return 0.0; - - double valueTimes2 = Math.Floor(value * 2 + MathUtil.Eps()); - if (valueTimes2 > 0 && valueTimes2 <= 20 && MathUtil.IsAlmostZero(value * 2 - valueTimes2)) - return valueTimes2 / 2; - - return null; - } - - internal static double? CanCacheLength(double unscaledValue, double value) - { - // We have a partial cache here, based on the unscaledValue. + // We have a partial cache here // Cache multiples of +/- 0.05 up to 10. - // Cache multiples of +/- 50 up to 10000. + // Cache multiples of +/- 0.5 up to 300. + // Cache multiples of +/- 5 reset. if (MathUtil.IsAlmostZero(value)) return 0.0; - // approximate tests for most common scales are good enough here. - bool isNegative = (unscaledValue < 0); - double unscaledPositiveValue = isNegative ? -unscaledValue : unscaledValue; - double eps = MathUtil.Eps(); - - if (unscaledPositiveValue <= 10.0 + eps) - { - double unscaledPositiveValueTimes2 = Math.Floor(unscaledPositiveValue * 2 + eps); - if (MathUtil.IsAlmostZero(unscaledPositiveValue * 2 - unscaledPositiveValueTimes2)) - { - double scaledPositiveValue = UnitUtil.ScaleLength(unscaledPositiveValueTimes2 / 2); - return isNegative ? -scaledPositiveValue : scaledPositiveValue; - } - return null; - } + double multiplier = 5.0; + if (Math.Abs(value) <= 10.0 + MathUtil.Eps()) + multiplier = 0.05; + else if (Math.Abs(value) <= 300.0 + MathUtil.Eps()) + multiplier = 0.5; - if (unscaledPositiveValue <= 10000.0 + eps) - { - double unscaledPositiveValueDiv50 = Math.Floor(unscaledPositiveValue / 50.0 + eps); - if (MathUtil.IsAlmostEqual(unscaledPositiveValue / 50.0, unscaledPositiveValueDiv50)) - { - double scaledPositiveValue = UnitUtil.ScaleLength(unscaledPositiveValueDiv50 * 50.0); - return isNegative ? -scaledPositiveValue : scaledPositiveValue; - } - } + double valueCorrected = Math.Floor(value / multiplier + MathUtil.Eps()); + if (MathUtil.IsAlmostZero(value / multiplier - valueCorrected)) + return valueCorrected * multiplier; return null; } - internal static double? CanCachePower(double value) + /// Create a count measure property. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateCountMeasureProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) { - // Allow caching of values between 0 and 300, in multiples of 5 - double eps = MathUtil.Eps(); - if (value < -eps || value > 300.0 + eps) - return null; - if (MathUtil.IsAlmostZero(value % 5.0)) - return Math.Truncate(value + 0.5); - return null; + IFCData countData = IFCDataUtil.CreateAsCountMeasure(value); + return CreateCommonProperty(file, propertyName, countData, valueType, null); } - internal static double? CanCacheTemperature(double value) + /// Create a count measure property. From IFC4x3 onward the value has been changed to Integer + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateCountMeasureProperty(IFCFile file, string propertyName, int value, PropertyValueType valueType) { - // Allow caching of integral temperatures and half-degrees. - if (MathUtil.IsAlmostEqual(value * 2.0, Math.Truncate(value * 2.0))) - return Math.Truncate(value * 2.0) / 2.0; - return null; + IFCData countData = IFCDataUtil.CreateAsCountMeasure(value); + return CreateCommonProperty(file, propertyName, countData, valueType, null); } - internal static double? CanCacheThermalTransmittance(double value) + /// Create a ClassificationReference property. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The created property handle. + public static IFCAnyHandle CreateClassificationReferenceProperty(IFCFile file, string propertyName, string value) { - // Allow caching of values between 0 and 6.0, in multiples of 0.05 - double eps = MathUtil.Eps(); - if (value < -eps || value > 6.0 + eps) - return null; - if (MathUtil.IsAlmostEqual(value * 20.0, Math.Truncate(value * 20.0))) - return Math.Truncate(value * 20.0) / 20.0; - return null; + IFCAnyHandle classificationReferenceHandle = + IFCInstanceExporter.CreateClassificationReference(file, null, value, null, null, null); + return IFCInstanceExporter.CreatePropertyReferenceValue(file, propertyName, null, null, classificationReferenceHandle); } /// - /// Create a real property. + /// Create a Time measure property from the element's parameter. /// /// The IFC file. - /// The name of the property. - /// The value of the property. + /// The Element. + /// The name of the parameter. + /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateRealProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) + public static IFCAnyHandle CreateTimePropertyFromElement(IFCFile file, Element elem, + string revitParameterName, string ifcPropertyName, PropertyValueType valueType) + { + return CreateDoublePropertyFromElement(file, elem, revitParameterName, ifcPropertyName, + "IfcTimeMeasure", SpecTypeId.Time, valueType); + } + + public static IFCAnyHandle CreateUserDefinedRealPropertyFromElement(IFCFile file, Element elem, + string revitParameterName, string ifcPropertyName, PropertyValueType valueType, ForgeTypeId specType, string unitTypeKey) { - IFCData realData = IFCDataUtil.CreateAsReal(value); - return CreateCommonProperty(file, propertyName, realData, valueType, null); + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, specType, valueType); + return CreateRealProperty(file, ifcPropertyName, doubleValues, valueType, unitTypeKey); } /// - /// Create a numeric property. + /// Create a currency measure property from the element's parameter. /// /// The IFC file. - /// The name of the property. - /// The value of the property. + /// The ExporterIFC. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateNumericProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) + public static IFCAnyHandle CreateCurrencyPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, + string revitParameterName, string ifcPropertyName, PropertyValueType valueType) { - IFCData NumericData = IFCDataUtil.CreateAsNumeric(value); - return CreateCommonProperty(file, propertyName, NumericData, valueType, null); + string measureName = ExporterCacheManager.UnitsCache.ContainsKey("CURRENCY") ? "IfcMonetaryMeasure" : "IfcReal"; + + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.Number, valueType); + return CreateRealProperty(file, ifcPropertyName, doubleValues, valueType, measureName); } - /// Create a real property, using a cached value if possible. - /// The IFC file. - /// The name of the property. - /// The value of the property. - /// The value type of the property. - /// The created or cached property handle. - public static IFCAnyHandle CreateRealPropertyFromCache(IFCFile file, string propertyName, double value, PropertyValueType valueType) + public static IFCAnyHandle CreateUserDefinedRealPropertyFromElement(IFCFile file, Element elem, + string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType, ForgeTypeId specType, string unitTypeKey) { - double? adjustedValue = CanCacheDouble(value); - bool canCache = adjustedValue.HasValue; - if (canCache) - { - value = adjustedValue.GetValueOrDefault(); - } - - IFCAnyHandle propertyHandle; - if (canCache) - { - propertyHandle = ExporterCacheManager.PropertyInfoCache.RealCache.Find(propertyName, value); - if (propertyHandle != null) - return propertyHandle; - } - - propertyHandle = CreateRealProperty(file, propertyName, value, valueType); + IFCAnyHandle propHnd = CreateUserDefinedRealPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType, specType, unitTypeKey); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; - if (canCache && !IFCAnyHandleUtil.IsNullOrHasNoValue(propertyHandle)) + if (revitBuiltInParam != BuiltInParameter.INVALID) { - ExporterCacheManager.PropertyInfoCache.RealCache.Add(propertyName, value, propertyHandle); + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreateUserDefinedRealPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType, specType, unitTypeKey); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; } - return propertyHandle; + return null; } - /// Create a numeric property, using a cached value if possible. + /// + /// Create a currency property from the element's parameter. + /// /// The IFC file. - /// The name of the property. - /// The value of the property. + /// The ExporterIFC. + /// The Element. + /// The name of the parameter. + /// The built in parameter to use, if revitParameterName isn't found. + /// The name of the property. /// The value type of the property. - /// The created or cached property handle. - public static IFCAnyHandle CreateNumericPropertyFromCache(IFCFile file, string propertyName, double value, PropertyValueType valueType) + /// The created property handle. + public static IFCAnyHandle CreateCurrencyPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, + string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - double? adjustedValue = CanCacheDouble(value); - bool canCache = adjustedValue.HasValue; - if (canCache) - { - value = adjustedValue.GetValueOrDefault(); - } - - IFCAnyHandle propertyHandle; - if (canCache) - { - propertyHandle = ExporterCacheManager.PropertyInfoCache.NumericCache.Find(propertyName, value); - if (propertyHandle != null) - return propertyHandle; - } - - propertyHandle = CreateNumericProperty(file, propertyName, value, valueType); + IFCAnyHandle propHnd = CreateCurrencyPropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; - if (canCache && !IFCAnyHandleUtil.IsNullOrHasNoValue(propertyHandle)) + if (revitBuiltInParam != BuiltInParameter.INVALID) { - ExporterCacheManager.PropertyInfoCache.NumericCache.Add(propertyName, value, propertyHandle); + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreateCurrencyPropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; } - return propertyHandle; + return null; } - /// Create a Thermodyanamic Temperature property, using a cached value if possible. + /// + /// Create a Time property from the element's parameter. + /// /// The IFC file. - /// The name of the property. - /// The value of the property. + /// The Element. + /// The name of the parameter. + /// The built in parameter to use, if revitParameterName isn't found. + /// The name of the property. /// The value type of the property. - /// The created or cached property handle. - public static IFCAnyHandle CreateThermodynamicTemperaturePropertyFromCache(IFCFile file, string propertyName, double value, PropertyValueType valueType) + /// The created property handle. + public static IFCAnyHandle CreateTimePropertyFromElement(IFCFile file, Element elem, + string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - double? adjustedValue = CanCacheTemperature(value); - bool canCache = adjustedValue.HasValue; - if (canCache) - value = adjustedValue.GetValueOrDefault(); + IFCAnyHandle propHnd = CreateTimePropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; - IFCAnyHandle propertyHandle; - if (canCache) + if (revitBuiltInParam != BuiltInParameter.INVALID) { - propertyHandle = ExporterCacheManager.PropertyInfoCache.ThermodynamicTemperatureCache.Find(propertyName, value); - if (propertyHandle != null) - return propertyHandle; + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreateTimePropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; } - propertyHandle = CreateThermodynamicTemperatureProperty(file, propertyName, value, valueType); - - if (canCache && !IFCAnyHandleUtil.IsNullOrHasNoValue(propertyHandle)) - ExporterCacheManager.PropertyInfoCache.ThermodynamicTemperatureCache.Add(propertyName, value, propertyHandle); - - return propertyHandle; + return null; } - /// Create a Power measure property, using a cached value if possible. + /// + /// Create an IfcClassificationReference property from the element's parameter. + /// /// The IFC file. - /// The name of the property. - /// The value of the property. - /// The value type of the property. - /// The created or cached property handle. - public static IFCAnyHandle CreatePowerPropertyFromCache(IFCFile file, string propertyName, double value, PropertyValueType valueType) + /// The ExporterIFC. + /// The Element. + /// The name of the parameter. + /// The name of the property. + /// The created property handle. + public static IFCAnyHandle CreateClassificationReferencePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, + string revitParameterName, string ifcPropertyName) { - double? adjustedValue = CanCachePower(value); - bool canCache = adjustedValue.HasValue; - if (canCache) - value = adjustedValue.GetValueOrDefault(); - - IFCAnyHandle propertyHandle; - if (canCache) - { - propertyHandle = ExporterCacheManager.PropertyInfoCache.PowerCache.Find(propertyName, value); - if (propertyHandle != null) - return propertyHandle; - } - - propertyHandle = CreatePowerProperty(file, propertyName, value, valueType); + if (elem == null) + return null; - if (canCache && !IFCAnyHandleUtil.IsNullOrHasNoValue(propertyHandle)) - ExporterCacheManager.PropertyInfoCache.PowerCache.Add(propertyName, value, propertyHandle); + string propertyValue; + if (ParameterUtil.GetStringValueFromElement(elem, revitParameterName, out propertyValue) != null) + return CreateClassificationReferenceProperty(file, ifcPropertyName, propertyValue); - return propertyHandle; + return null; } - /// Create a Thermal Transmittance property, using a cached value if possible. + /// + /// Create a generic measure property from the element's parameter. + /// /// The IFC file. - /// The name of the property. - /// The value of the property. - /// The value type of the property. - /// The created or cached property handle. - public static IFCAnyHandle CreateThermalTransmittancePropertyFromCache(IFCFile file, string propertyName, double value, PropertyValueType valueType) + /// The ExporterIFC. + /// The Element. + /// The name of the parameter. + /// The name of the property. + /// The IfcMeasure type of the property. + /// Identifier of the property spec. + /// The property value type of the property. + /// The created property handle. + private static IFCAnyHandle CreateDoublePropertyFromElement(IFCFile file, Element elem, + string revitParameterName, string ifcPropertyName, string measureType, ForgeTypeId specTypeId, PropertyValueType valueType) { - double? adjustedValue = CanCacheThermalTransmittance(value); - bool canCache = adjustedValue.HasValue; - if (canCache) - value = adjustedValue.GetValueOrDefault(); - - IFCAnyHandle propertyHandle; - if (canCache) - { - propertyHandle = ExporterCacheManager.PropertyInfoCache.ThermalTransmittanceCache.Find(propertyName, value); - if (propertyHandle != null) - return propertyHandle; - } + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, specTypeId, valueType); - propertyHandle = CreateThermalTransmittanceProperty(file, propertyName, value, valueType); + IList doubleData = new List(); + foreach (var val in doubleValues) + doubleData.Add(val.HasValue ? IFCData.CreateDoubleOfType(val.Value, measureType) : null); - if (canCache && !IFCAnyHandleUtil.IsNullOrHasNoValue(propertyHandle)) - ExporterCacheManager.PropertyInfoCache.ThermalTransmittanceCache.Add(propertyName, value, propertyHandle); - - return propertyHandle; + return CreateCommonPropertyFromList(file, ifcPropertyName, doubleData, valueType, null); } /// - /// Creates a length measure property or gets one from cache. + /// Create an IfcClassificationReference property from the element's parameter. /// /// The IFC file. - /// The name of the property. - /// The unscaled value of the property, used for cache purposes. - /// The value type of the property. + /// The ExporterIFC. + /// The Element. + /// The name of the parameter. + /// The built in parameter to use, if revitParameterName isn't found. + /// The name of the property. /// The created property handle. - public static IFCAnyHandle CreateLengthMeasurePropertyFromCache(IFCFile file, string propertyName, double value, - PropertyValueType valueType) + public static IFCAnyHandle CreateClassificationReferencePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, + string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName) { - double unscaledValue = UnitUtil.UnscaleLength(value); + IFCAnyHandle propHnd = CreateClassificationReferencePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; - double? adjustedValue = CanCacheLength(unscaledValue, value); - bool canCache = adjustedValue.HasValue; - if (canCache) + if (revitBuiltInParam != BuiltInParameter.INVALID) { - value = adjustedValue.GetValueOrDefault(); + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreateClassificationReferencePropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; } - IFCAnyHandle propertyHandle; - if (canCache) - { - propertyHandle = ExporterCacheManager.PropertyInfoCache.LengthMeasureCache.Find(propertyName, value); - if (propertyHandle != null) - return propertyHandle; - } - - switch (valueType) - { - case PropertyValueType.EnumeratedValue: - { - IList valueList = new List(); - valueList.Add(IFCDataUtil.CreateAsLengthMeasure(value)); - propertyHandle = IFCInstanceExporter.CreatePropertyEnumeratedValue(file, propertyName, null, valueList, null); - break; - } - case PropertyValueType.SingleValue: - propertyHandle = IFCInstanceExporter.CreatePropertySingleValue(file, propertyName, null, IFCDataUtil.CreateAsLengthMeasure(value), null); - break; - default: - throw new InvalidOperationException("Missing case!"); - } - - if (canCache && !IFCAnyHandleUtil.IsNullOrHasNoValue(propertyHandle)) - { - ExporterCacheManager.PropertyInfoCache.LengthMeasureCache.Add(propertyName, value, propertyHandle); - } - - return propertyHandle; + return null; } /// - /// Creates a vapor permeability measure property. + /// Create a label property from the element's parameter. /// /// The IFC file. - /// The name of the property. - /// The value of the property. + /// The Element. + /// The name of the parameter. + /// The name of the property. /// The value type of the property. + /// The type of the enum, null if valueType isn't EnumeratedValue. /// The created property handle. - public static IFCAnyHandle CreateVaporPermeabilityMeasureProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) + public static IFCAnyHandle CreateLabelPropertyFromElement(IFCFile file, Element elem, string revitParameterName, string ifcPropertyName, + PropertyValueType valueType, Type propertyEnumerationType) { - IFCData vaporPermeabilityData = IFCDataUtil.CreateAsVaporPermeabilityMeasure(value); - return CreateCommonProperty(file, propertyName, vaporPermeabilityData, valueType, null); - } + if (elem == null) + return null; - /// - /// Creates a volume measure property. - /// - /// The IFC file. - /// The name of the property. - /// The value of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateVolumeMeasureProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) - { - IFCData volumeData = IFCDataUtil.CreateAsVolumeMeasure(value); - return CreateCommonProperty(file, propertyName, volumeData, valueType, null); - } + string propertyValue; + Parameter parameter = ParameterUtil.GetStringValueFromElement(elem, revitParameterName, out propertyValue); + if (parameter != null) + return CreateLabelPropertyFromCache(file, parameter.Id, ifcPropertyName, propertyValue, valueType, false, propertyEnumerationType); - /// - /// Creates a sound power measure property. - /// - /// The IFC file. - /// The name of the property. - /// The value of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateSoundPowerMeasureProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) - { - IFCData soundPowerData = IFCDataUtil.CreateAsSoundPowerMeasure(value); - return CreateCommonProperty(file, propertyName, soundPowerData, valueType, null); + return null; } /// - /// Creates a sound pressure measure property. + /// Create a label property from the element's parameter. /// /// The IFC file. - /// The name of the property. - /// The value of the property. + /// The Element. + /// The name of the parameter. + /// The built in parameter. + /// The name of the property. /// The value type of the property. + /// The type of the enum, null if valueType isn't EnumeratedValue. /// The created property handle. - public static IFCAnyHandle CreateSoundPressureMeasureProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) + public static IFCAnyHandle CreateLabelPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType, Type propertyEnumerationType) { - IFCData soundPressureData = IFCDataUtil.CreateAsSoundPressureMeasure(value); - return CreateCommonProperty(file, propertyName, soundPressureData, valueType, null); - } + // For Instance + IFCAnyHandle propHnd = CreateLabelPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType, + propertyEnumerationType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; - /// - /// Creates Specific Heat Capacity measure property. - /// - /// The IFC file. - /// The name of the property. - /// The value of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateSpecificHeatCapacityMeasureProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) - { - IFCData specificHeatCapacityData = IFCDataUtil.CreateAsSpecificHeatCapacityMeasure(value); - return CreateCommonProperty(file, propertyName, specificHeatCapacityData, valueType, null); + if (revitBuiltInParam != BuiltInParameter.INVALID) + { + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreateLabelPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType, propertyEnumerationType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; + } + + return null; } /// - /// Creates DynamicViscosity measure property. + /// Create an identifier property from the element's parameter. /// /// The IFC file. - /// The name of the property. - /// The value of the property. + /// The Element. + /// The name of the parameter. + /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateDynamicViscosityMeasureProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) + public static IFCAnyHandle CreateIdentifierPropertyFromElement(IFCFile file, Element elem, string revitParameterName, string ifcPropertyName, PropertyValueType valueType) { - IFCData dynamicViscosityData = IFCDataUtil.CreateAsDynamicViscosityMeasure(value); - return CreateCommonProperty(file, propertyName, dynamicViscosityData, valueType, null); + if (elem == null) + return null; + + string propertyValue; + if (ParameterUtil.GetStringValueFromElement(elem, revitParameterName, out propertyValue) != null) + return CreateIdentifierPropertyFromCache(file, ifcPropertyName, propertyValue, valueType); + + return null; } /// - /// Creates ThermalConductivity measure property. + /// Create an identifier property from the element's parameter. /// /// The IFC file. - /// The name of the property. - /// The value of the property. + /// The Element. + /// The name of the parameter. + /// The built in parameter. + /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateThermalConductivityMeasureProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) + public static IFCAnyHandle CreateIdentifierPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - IFCData thermalConductivityData = IFCDataUtil.CreateAsThermalConductivityMeasure(value); - return CreateCommonProperty(file, propertyName, thermalConductivityData, valueType, null); + // For Instance + IFCAnyHandle propHnd = CreateIdentifierPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; + + if (revitBuiltInParam != BuiltInParameter.INVALID) + { + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreateIdentifierPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; + } + + return null; } /// - /// Creates ThermalExpansionCoefficient measure property. + /// Create a boolean property from the element's parameter. /// /// The IFC file. - /// The name of the property. - /// The value of the property. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateThermalExpansionCoefficientMeasureProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) + public static IFCAnyHandle CreateBooleanPropertyFromElement(IFCFile file, Element elem, + string revitParameterName, string ifcPropertyName, PropertyValueType valueType) { - IFCData thermalExpansionCoefficientData = IFCDataUtil.CreateAsThermalExpansionCoefficientMeasure(value); - return CreateCommonProperty(file, propertyName, thermalExpansionCoefficientData, valueType, null); + int propertyValue; + if (ParameterUtil.GetIntValueFromElement(elem, revitParameterName, out propertyValue) != null) + return CreateBooleanPropertyFromCache(file, ifcPropertyName, propertyValue != 0, valueType); + if (ParameterUtil.GetIntValueFromElement(elem, ifcPropertyName, out propertyValue) != null) + return CreateBooleanPropertyFromCache(file, ifcPropertyName, propertyValue != 0, valueType); + + return null; } /// - /// Create a positive length measure property. + /// Create a logical property from the element's or type's parameter. /// /// The IFC file. - /// The name of the property. - /// The value of the property. + /// The Element. + /// The name of the parameter. + /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreatePositiveLengthMeasureProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) + public static IFCAnyHandle CreateLogicalPropertyFromElement(IFCFile file, Element elem, + string revitParameterName, string ifcPropertyName, PropertyValueType valueType) { - if (value > MathUtil.Eps()) + IFCLogical ifcLogical = IFCLogical.Unknown; + int propertyValue; + if (ParameterUtil.GetIntValueFromElement(elem, revitParameterName, out propertyValue) != null) { - IFCData posLengthData = IFCDataUtil.CreateAsPositiveLengthMeasure(value); - return CreateCommonProperty(file, propertyName, posLengthData, valueType, null); + ifcLogical = propertyValue != 0 ? IFCLogical.True : IFCLogical.False; } - return null; - } - /// - /// Create a linear velocity measure property. - /// - /// The IFC file. - /// The name of the property. - /// The value of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateLinearVelocityMeasureProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) - { - IFCData linearVelocityData = IFCDataUtil.CreateAsLinearVelocityMeasure(value); - return CreateCommonProperty(file, propertyName, linearVelocityData, valueType, null); + return CreateLogicalPropertyFromCache(file, ifcPropertyName, ifcLogical, valueType); } - - /// - /// Create a ratio measure property. + /// Create an integer property from the element's parameter. /// /// The IFC file. - /// The name of the property. - /// The value of the property. + /// The Element. + /// The name of the parameter. + /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateRatioMeasureProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) + public static IFCAnyHandle CreateIntegerPropertyFromElement(IFCFile file, Element elem, + string revitParameterName, string ifcPropertyName, PropertyValueType valueType) { - IFCData data = IFCDataUtil.CreateRatioMeasureData(value); - return CreateCommonProperty(file, propertyName, data, valueType, null); + int propertyValue; + if (ParameterUtil.GetIntValueFromElement(elem, revitParameterName, out propertyValue) != null) + return CreateIntegerPropertyFromCache(file, ifcPropertyName, propertyValue, valueType); + + return null; } /// - /// Create a normalised ratio measure property. + /// Create a ratio measure data from string value. /// - /// The IFC file. - /// The name of the property. - /// The value of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateNormalisedRatioMeasureProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) + /// The values of the property. + /// The created property data. + public static IFCData CreateRatioMeasureDataFromString(string value) { - IFCData data = IFCDataUtil.CreateNormalisedRatioMeasureData(value); - return CreateCommonProperty(file, propertyName, data, valueType, null); + double propertyValue; + if (Double.TryParse(value, out propertyValue)) + return IFCDataUtil.CreateRatioMeasureData(propertyValue); + + return null; } + + /// - /// Create a positive ratio measure property. + /// Create a normalised ratio measure data from string value. /// - /// The IFC file. - /// The name of the property. - /// The value of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreatePositiveRatioMeasureProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) + /// The values of the property. + /// The created property data. + public static IFCData CreateNormalisedRatioMeasureDataFromString(string value) { - IFCData data = IFCDataUtil.CreatePositiveRatioMeasureData(value); - return CreateCommonProperty(file, propertyName, data, valueType, null); + double propertyValue; + if (Double.TryParse(value, out propertyValue)) + return IFCDataUtil.CreateNormalisedRatioMeasureData(propertyValue); + + return null; } + /// - /// Create a label property. + /// Create a positive ratio measure data from string value. /// - /// The IFC file. - /// The name of the property. - /// The value of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreatePlaneAngleMeasureProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) + /// The values of the property. + /// The created property data. + public static IFCData CreatePositiveRatioMeasureDataFromString(string value) { - IFCData planeAngleData = IFCDataUtil.CreateAsPlaneAngleMeasure(value); - return CreateCommonProperty(file, propertyName, planeAngleData, valueType, null); + double propertyValue; + if (Double.TryParse(value, out propertyValue)) + return IFCDataUtil.CreatePositiveRatioMeasureData(propertyValue); + + return null; } /// - /// Create a label property, or retrieve from cache. + /// Create a count measure property from the element's parameter. /// /// The IFC file. - /// The name of the property. - /// The value of the property. + /// The ExporterIFC. + /// The Element. + /// The name of the parameter. + /// The name of the property. /// The value type of the property. - /// The created or cached property handle. - public static IFCAnyHandle CreatePlaneAngleMeasurePropertyFromCache(IFCFile file, string propertyName, double value, PropertyValueType valueType) + /// The created property handle. + public static IFCAnyHandle CreateCountMeasurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, + string revitParameterName, string ifcPropertyName, PropertyValueType valueType) { - // We have a partial cache here - we will only cache multiples of 15 degrees. - bool canCache = false; - double degreesDiv15 = Math.Floor(value / 15.0 + 0.5); - double integerDegrees = degreesDiv15 * 15.0; - if (MathUtil.IsAlmostEqual(value, integerDegrees)) - { - canCache = true; - value = integerDegrees; - } - - IFCAnyHandle propertyHandle; - if (canCache) + int propertyValue; + double propertyValueReal; + if (ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValueReal) != null) { - propertyHandle = ExporterCacheManager.PropertyInfoCache.PlaneAngleCache.Find(propertyName, value); - if (propertyHandle != null) - return propertyHandle; + if (ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4x3) + { + return CreateCountMeasureProperty(file, ifcPropertyName, propertyValueReal, valueType); + } + else if (MathUtil.IsAlmostInteger(propertyValueReal)) + { + propertyValue = (int)Math.Floor(propertyValueReal); + return CreateCountMeasureProperty(file, ifcPropertyName, propertyValue, valueType); + } } - propertyHandle = CreatePlaneAngleMeasureProperty(file, propertyName, value, valueType); - - if (canCache && !IFCAnyHandleUtil.IsNullOrHasNoValue(propertyHandle)) - { - ExporterCacheManager.PropertyInfoCache.PlaneAngleCache.Add(propertyName, value, propertyHandle); - } + if (ParameterUtil.GetIntValueFromElement(elem, revitParameterName, out propertyValue) != null) + return CreateCountMeasureProperty(file, ifcPropertyName, propertyValue, valueType); - return propertyHandle; + return null; } /// - /// Create a area measure property. + /// Create a count measure property from the element's parameter. /// /// The IFC file. - /// The name of the property. - /// The value of the property. + /// The ExporterIFC. + /// The Element. + /// The name of the parameter. + /// The built in parameter to use, if revitParameterName isn't found. + /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateAreaMeasureProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) + public static IFCAnyHandle CreateCountMeasurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, + string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - IFCData areaData = IFCDataUtil.CreateAsAreaMeasure(value); - return CreateCommonProperty(file, propertyName, areaData, valueType, null); - } + IFCAnyHandle propHnd = CreateCountMeasurePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; - /// - /// Create a Acceleration measure property. - /// - /// The IFC file. - /// The name of the property. - /// The value of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateAccelerationMeasureProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) - { - IFCData accelerationData = IFCDataUtil.CreateAsAccelerationMeasure(value); - return CreateCommonProperty(file, propertyName, accelerationData, valueType, null); - } + if (revitBuiltInParam != BuiltInParameter.INVALID) + { + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreateCountMeasurePropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; + } - /// - /// Create a Energy measure property. - /// - /// The IFC file. - /// The name of the property. - /// The value of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateEnergyMeasureProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) - { - IFCData energyData = IFCDataUtil.CreateAsEnergyMeasure(value); - return CreateCommonProperty(file, propertyName, energyData, valueType, null); + return null; } /// - /// Create a LinearMoment measure property. + /// Creates the shared beam and column QTO values. /// - /// The IFC file. - /// The name of the property. - /// The value of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateLinearMomentMeasureProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) + /// + /// This code uses the native implementation for creating these quantities, and the native class for storing the information. + /// This will be obsoleted. + /// + /// The exporter. + /// The element handle. + /// The beam or column element. + /// The FamilyTypeInfo containing the appropriate data. + /// The list of geometries for the exported column only, used if split walls and columns is set. + /// The geomObjects is used if we have the split by level option. It is intended only for columns, as beams and members are not split by level. + /// In this case, we use the solids in the list to determine the real volume of the exported objects. If the list contains meshes, we won't export the volume at all. + public static void CreateBeamColumnBaseQuantities(ExporterIFC exporterIFC, IFCAnyHandle elemHandle, Element element, FamilyTypeInfo typeInfo, IList geomObjects) { - IFCData linearMomentData = IFCDataUtil.CreateAsLinearMomentMeasure(value); - return CreateCommonProperty(file, propertyName, linearMomentData, valueType, null); - } + // Make sure QTO export is enabled. + if (!ExporterCacheManager.ExportOptionsCache.ExportBaseQuantities || (ExporterCacheManager.ExportOptionsCache.ExportAsCOBIE)) + return; - /// - /// Create a MassPerLength measure property. - /// - /// The IFC file. - /// The name of the property. - /// The value of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateMassPerLengthMeasureProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) - { - IFCData massPerLengthData = IFCDataUtil.CreateAsMassPerLengthMeasure(value); - return CreateCommonProperty(file, propertyName, massPerLengthData, valueType, null); - } + IFCFile file = exporterIFC.GetFile(); + HashSet quantityHnds = new HashSet(); + double scaledLength = typeInfo.extraParams.ScaledLength; + //According to investigation of current code the passed in typeInfo contains grossArea + double scaledGrossArea = typeInfo.extraParams.ScaledArea; + double crossSectionArea = scaledGrossArea; + double scaledOuterPerimeter = typeInfo.extraParams.ScaledOuterPerimeter; + double scaledInnerPerimeter = typeInfo.extraParams.ScaledInnerPerimeter; + double outSurfaceArea = 0.0; - /// - /// Create a Torque measure property. - /// - /// The IFC file. - /// The name of the property. - /// The value of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateTorqueMeasureProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) - { - IFCData torqueData = IFCDataUtil.CreateAsTorqueMeasure(value); - return CreateCommonProperty(file, propertyName, torqueData, valueType, null); - } + if (scaledLength > MathUtil.Eps()) + { + IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityLength(file, "Length", null, null, scaledLength); + quantityHnds.Add(quantityHnd); + } - /// - /// Create a LinearStiffness measure property. - /// - /// The IFC file. - /// The name of the property. - /// The value of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateLinearStiffnessMeasureProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) - { - IFCData linearStiffnessData = IFCDataUtil.CreateAsLinearStiffnessMeasure(value); - return CreateCommonProperty(file, propertyName, linearStiffnessData, valueType, null); + if (MathUtil.AreaIsAlmostZero(crossSectionArea)) + { + if (element != null) + { + ParameterUtil.GetDoubleValueFromElement(element, BuiltInParameter.HOST_AREA_COMPUTED, out crossSectionArea); + crossSectionArea = UnitUtil.ScaleArea(crossSectionArea); + } + } + + if (!MathUtil.AreaIsAlmostZero(crossSectionArea)) + { + IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityArea(file, "CrossSectionArea", null, null, crossSectionArea); + quantityHnds.Add(quantityHnd); + } + + if (!MathUtil.AreaIsAlmostZero(scaledGrossArea) && !MathUtil.IsAlmostZero(scaledLength) && !MathUtil.IsAlmostZero(scaledOuterPerimeter)) + { + double scaledPerimeter = scaledOuterPerimeter + scaledInnerPerimeter; + //According to the IFC documentation, OuterSurfaceArea does not include the end caps area, only Length * Perimeter + outSurfaceArea = UnitUtil.ScaleArea(UnitUtil.UnscaleLength(scaledLength) * UnitUtil.UnscaleLength(scaledPerimeter)); + IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityArea(file, "OuterSurfaceArea", null, null, outSurfaceArea); + quantityHnds.Add(quantityHnd); + } + + // Compute GrossSurfaceArea if both CrossSectionAre and OuterSurfaceArea cannot be determined separately + if (MathUtil.AreaIsAlmostZero(crossSectionArea) && MathUtil.AreaIsAlmostZero(outSurfaceArea)) + { + double scaledPerimeter = scaledOuterPerimeter + scaledInnerPerimeter; + double grossSurfaceArea = scaledGrossArea * 2 + UnitUtil.ScaleArea(UnitUtil.UnscaleLength(scaledLength) * UnitUtil.UnscaleLength(scaledPerimeter)); + IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityArea(file, "GrossSurfaceArea", null, null, grossSurfaceArea); + quantityHnds.Add(quantityHnd); + } + + double grossVolume = UnitUtil.ScaleVolume(UnitUtil.UnscaleLength(scaledLength) * UnitUtil.UnscaleArea(scaledGrossArea)); + double netVolume = 0.0; + if (element != null) + { + // If we are splitting columns, we will look at the actual geometry used when exporting this segment + // of the column, but only if we have the geomObjects passed in. + if (geomObjects != null && ExporterCacheManager.ExportOptionsCache.WallAndColumnSplitting) + { + foreach (GeometryObject geomObj in geomObjects) + { + // We don't suport calculating the volume of Meshes at this time. + if (geomObj is Mesh) + { + netVolume = 0.0; + break; + } + + if (geomObj is Solid) + netVolume += (geomObj as Solid).Volume; + } + } + else + ParameterUtil.GetDoubleValueFromElement(element, BuiltInParameter.HOST_VOLUME_COMPUTED, out netVolume); + netVolume = UnitUtil.ScaleVolume(netVolume); + } + + if (!MathUtil.VolumeIsAlmostZero(grossVolume)) + { + IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityVolume(file, "GrossVolume", null, null, grossVolume); + quantityHnds.Add(quantityHnd); + } + + if (!MathUtil.VolumeIsAlmostZero(netVolume)) + { + IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityVolume(file, "NetVolume", null, null, netVolume); + quantityHnds.Add(quantityHnd); + } + + string quantitySetName = string.Empty; + if (!ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4) + { + if (IFCAnyHandleUtil.IsSubTypeOf(elemHandle, Common.Enums.IFCEntityType.IfcColumn)) + quantitySetName = "Qto_ColumnBaseQuantities"; + if (IFCAnyHandleUtil.IsSubTypeOf(elemHandle, Common.Enums.IFCEntityType.IfcBeam)) + quantitySetName = "Qto_BeamBaseQuantities"; + if (IFCAnyHandleUtil.IsSubTypeOf(elemHandle, Common.Enums.IFCEntityType.IfcMember)) + quantitySetName = "Qto_MemberBaseQuantities"; + } + CreateAndRelateBaseQuantities(file, exporterIFC, elemHandle, quantityHnds, quantitySetName); } /// - /// Create a AngularVelocity measure property. + /// Creates the spatial element quantities required by GSA before COBIE and adds them to the export. /// - /// The IFC file. - /// The name of the property. - /// The value of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateAngularVelocityMeasureProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) + /// The exporter. + /// The element handle. + /// The quantity name. + /// The area name. + /// The area. + public static void CreatePreCOBIEGSAQuantities(ExporterIFC exporterIFC, IFCAnyHandle elemHnd, string quantityName, string areaName, double area) { - IFCData angularVelocityData = IFCDataUtil.CreateAsAngularVelocityMeasure(value); - return CreateCommonProperty(file, propertyName, angularVelocityData, valueType, null); + IFCFile file = exporterIFC.GetFile(); + IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; + IFCAnyHandle areaQuantityHnd = IFCInstanceExporter.CreateQuantityArea(file, quantityName, null, null, area); + HashSet areaQuantityHnds = new HashSet(); + areaQuantityHnds.Add(areaQuantityHnd); + + PropertyUtil.CreateAndRelateBaseQuantities(file, exporterIFC, elemHnd, areaQuantityHnds, quantityName, null, areaName); } /// - /// Create a ThermalResistance measure property. + /// Creates the opening quantities and adds them to the export. /// - /// The IFC file. - /// The name of the property. - /// The value of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateThermalResistanceMeasureProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) + /// The exporter. + /// The opening element handle. + /// The extrusion creation data. + public static void CreateOpeningQuantities(ExporterIFC exporterIFC, IFCAnyHandle openingElement, IFCExportBodyParams extraParams) { - IFCData thermalResistanceData = IFCDataUtil.CreateAsThermalResistanceMeasure(value); - return CreateCommonProperty(file, propertyName, thermalResistanceData, valueType, null); + IFCFile file = exporterIFC.GetFile(); + HashSet quantityHnds = new HashSet(); + if (extraParams.ScaledLength > MathUtil.Eps()) + { + IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityLength(file, "Depth", null, null, extraParams.ScaledLength); + quantityHnds.Add(quantityHnd); + } + if (extraParams.ScaledHeight > MathUtil.Eps()) + { + IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityLength(file, "Height", null, null, extraParams.ScaledHeight); + quantityHnds.Add(quantityHnd); + quantityHnd = IFCInstanceExporter.CreateQuantityLength(file, "Width", null, null, extraParams.ScaledWidth); + quantityHnds.Add(quantityHnd); + } + else if (extraParams.ScaledArea > MathUtil.Eps()) + { + IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityArea(file, "Area", null, null, extraParams.ScaledArea); + quantityHnds.Add(quantityHnd); + } + + string quantitySetName = string.Empty; + if (!ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4) + { + quantitySetName = "Qto_OpeningElementBaseQuantities"; + } + CreateAndRelateBaseQuantities(file, exporterIFC, openingElement, quantityHnds, quantitySetName); } /// - /// Create a WarpingConstant measure property. + /// Creates and caches area and volume base quantities for slabs. /// - /// The IFC file. - /// The name of the property. - /// The value of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateWarpingConstantMeasureProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) + /// The exporter. + /// The slab handle. + /// The IFCExportBodyParams containing the slab extrusion creation data. + /// The slab outer loop. + public static void CreateSlabBaseQuantities(ExporterIFC exporterIFC, IFCAnyHandle slabHnd, IFCExportBodyParams extrusionData, CurveLoop outerCurveLoop) { - IFCData warpingConstantData = IFCDataUtil.CreateAsWarpingConstantMeasure(value); - return CreateCommonProperty(file, propertyName, warpingConstantData, valueType, null); - } + if (extrusionData != null) + { + IFCFile file = exporterIFC.GetFile(); + HashSet quantityHnds = new HashSet(); - /// Create a count measure property. - /// The IFC file. - /// The name of the property. - /// The value of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateCountMeasureProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) - { - IFCData countData = IFCDataUtil.CreateAsCountMeasure(value); - return CreateCommonProperty(file, propertyName, countData, valueType, null); - } + double netArea = extrusionData.ScaledArea; + if (!MathUtil.IsAlmostZero(netArea)) + { + IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityArea(file, "NetArea", null, null, netArea); + quantityHnds.Add(quantityHnd); + } - /// Create a count measure property. From IFC4x3 onward the value has been changed to Integer - /// The IFC file. - /// The name of the property. - /// The value of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateCountMeasureProperty(IFCFile file, string propertyName, int value, PropertyValueType valueType) - { - IFCData countData = IFCDataUtil.CreateAsCountMeasure(value); - return CreateCommonProperty(file, propertyName, countData, valueType, null); - } + //The length, area and volume may have different base length units, it safer to unscale and rescale the results. + double unscaledArea = UnitUtil.UnscaleArea(netArea); + double unscaledLength = UnitUtil.UnscaleLength(extrusionData.ScaledLength); + double netVolume = UnitUtil.ScaleVolume(unscaledArea * unscaledLength); + if (!MathUtil.IsAlmostZero(netVolume)) + { + IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityArea(file, "NetVolume", null, null, netVolume); + quantityHnds.Add(quantityHnd); + } - /// Create a ThermodynamicTemperature property. - /// The IFC file. - /// The name of the property. - /// The value of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateThermodynamicTemperatureProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) - { - IFCData thermodynamicTemperatureMeasureData = IFCDataUtil.CreateAsThermodynamicTemperatureMeasure(value); - return CreateCommonProperty(file, propertyName, thermodynamicTemperatureMeasureData, valueType, null); - } + if (outerCurveLoop != null) + { + double unscaledSlabGrossArea = ExporterIFCUtils.ComputeAreaOfCurveLoops(new List() { outerCurveLoop }); + double scaledSlabGrossArea = UnitUtil.ScaleArea(unscaledSlabGrossArea); + if (!MathUtil.IsAlmostZero(scaledSlabGrossArea)) + { + IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityArea(file, "GrossArea", null, null, scaledSlabGrossArea); + quantityHnds.Add(quantityHnd); + } - /// Create a ClassificationReference property. - /// The IFC file. - /// The name of the property. - /// The value of the property. - /// The created property handle. - public static IFCAnyHandle CreateClassificationReferenceProperty(IFCFile file, string propertyName, string value) - { - IFCAnyHandle classificationReferenceHandle = - IFCInstanceExporter.CreateClassificationReference(file, null, value, null, null, null); - return IFCInstanceExporter.CreatePropertyReferenceValue(file, propertyName, null, null, classificationReferenceHandle); - } + double grossVolume = UnitUtil.ScaleVolume(unscaledArea * unscaledLength); + if (!MathUtil.IsAlmostZero(grossVolume)) + { + IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityArea(file, "GrossVolume", null, null, grossVolume); + quantityHnds.Add(quantityHnd); + } + } - /// Create an IlluminanceMeasure property. - /// The IFC file. - /// The name of the property. - /// The value of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateIlluminanceProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) - { - IFCData illuminanceData = IFCDataUtil.CreateAsIlluminanceMeasure(value); - return CreateCommonProperty(file, propertyName, illuminanceData, valueType, null); + ExporterCacheManager.BaseQuantitiesCache.Add(slabHnd, quantityHnds); + } } - - /// Create a LuminousFluxMeasure property. - /// The IFC file. - /// The name of the property. - /// The value of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateLuminousFluxMeasureProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) + /// + /// Creates the wall base quantities and adds them to the export. + /// + /// The exporter. + /// The wall element. + /// The wall handle. + /// The list of solids for the entity created for the wall element. + /// The list of meshes for the entity created for the wall element. + /// The scaled length. + /// The scaled depth. + /// The scaled foot print area. + /// If we are splitting walls by level, the list of solids and meshes represent the currently + /// exported section of wall, not the entire wall. + public static void CreateWallBaseQuantities(ExporterIFC exporterIFC, Wall wallElement, + IList solids, IList meshes, + IFCAnyHandle wallHnd, + double scaledLength, double scaledDepth, double scaledFootPrintArea, + IFCExportBodyParams extrusionData, HashSet widthAsComplexQty = null) { - IFCData luminousFluxData = IFCDataUtil.CreateAsLuminousFluxMeasure(value); - return CreateCommonProperty(file, propertyName, luminousFluxData, valueType, null); - } + IFCFile file = exporterIFC.GetFile(); + HashSet quantityHnds = new HashSet(); + if (scaledDepth > MathUtil.Eps()) + { + IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityLength(file, "Height", null, null, scaledDepth); + quantityHnds.Add(quantityHnd); + } - /// Create a LuminousIntensityMeasure property. - /// The IFC file. - /// The name of the property. - /// The value of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateLuminousIntensityProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) - { - IFCData luminousIntensityData = IFCDataUtil.CreateAsLuminousIntensityMeasure(value); - return CreateCommonProperty(file, propertyName, luminousIntensityData, valueType, null); - } + if (!MathUtil.IsAlmostZero(scaledLength)) + { + IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityLength(file, "Length", null, null, scaledLength); + quantityHnds.Add(quantityHnd); + } + else if (wallElement.Location != null) + { + Curve wallAxis = (wallElement.Location as LocationCurve).Curve; + if (wallAxis != null) + { + double axisLength = UnitUtil.ScaleLength(wallAxis.Length); + IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityLength(file, "Length", null, null, axisLength); + quantityHnds.Add(quantityHnd); + } + } - /// Create a ForceMeasure property. - /// The IFC file. - /// The name of the property. - /// The value of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateForceProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) - { - IFCData forceData = IFCDataUtil.CreateAsForceMeasure(value); - return CreateCommonProperty(file, propertyName, forceData, valueType, null); - } - /// Create a LinearForceMeasure property. - /// The IFC file. - /// The name of the property. - /// The value of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateLinearForceProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) - { - IFCData linearForceData = IFCDataUtil.CreateAsLinearForceMeasure(value); - return CreateCommonProperty(file, propertyName, linearForceData, valueType, null); - } + double scaledWidth = 0.0; + if (wallElement != null) + { + scaledWidth = UnitUtil.ScaleLength(wallElement.Width); + if (!MathUtil.IsAlmostZero(scaledWidth)) + { + if ((widthAsComplexQty?.Count ?? 0) == 0) + { + IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityLength(file, "Width", null, null, scaledWidth); + quantityHnds.Add(quantityHnd); + } + else + { + quantityHnds.UnionWith(widthAsComplexQty); + } + } + } - public static IFCAnyHandle CreateLinearForcePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) - { + if (!MathUtil.IsAlmostZero(scaledFootPrintArea)) + { + IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityArea(file, "GrossFootprintArea", null, null, scaledFootPrintArea); + quantityHnds.Add(quantityHnd); + } - IFCAnyHandle propHnd = CreateDoublePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, - "IfcLinearForceMeasure", SpecTypeId.LinearForce, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; + double netArea = 0; + double grossArea = 0; + double volume = 0; - if (revitBuiltInParam != BuiltInParameter.INVALID) + // We will only assign the area if we have all solids that we are exporting; we won't bother calcuting values for Meshes. + if (solids != null && (meshes == null || meshes.Count == 0)) { - string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateDoublePropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, - "IfcLinearForceMeasure", SpecTypeId.LinearForce, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; + //To determine the side of the wall that is suitable for calculating BaseQuantities, + //we group the faces by normal and calculate the total area of each side. + Dictionary, double)> wallSides = new Dictionary, double)>(); + foreach (Solid solid in solids) + { + foreach (Face face in solid.Faces) + { + XYZ faceNormal = face.ComputeNormal(new UV(0, 0)); + if (MathUtil.IsAlmostZero(faceNormal.Z)) + { + double faceArea = face.Area; + if (wallSides.Any()) + { + bool faceAdded = false; + foreach (var wallSide in wallSides) + { + if (faceNormal.IsAlmostEqualTo(wallSide.Key)) + { + List sideFaces = wallSide.Value.Item1; + sideFaces.Add(face); + double sumArea = wallSide.Value.Item2 + faceArea; + wallSides[wallSide.Key] = ( sideFaces, sumArea); + faceAdded = true; + break; + } + } + if(!faceAdded) + { + wallSides.Add(faceNormal, (new List { face }, face.Area)); + } + } + else + { + wallSides.Add(faceNormal, (new List { face }, face.Area)); + } + } + } + volume += solid.Volume; + } + + KeyValuePair, double)> largestSide = new KeyValuePair, double)>(); + foreach (var wallSide in wallSides) + { + if (wallSide.Value.Item2 > largestSide.Value.Item2) + largestSide = wallSide; + } + + List facesOfLargestWallSide = largestSide.Value.Item1; + netArea = largestSide.Value.Item2; + + foreach (Face face in facesOfLargestWallSide) + { + double largestFaceGrossArea = 0.0; + IList fCurveLoops = face.GetEdgesAsCurveLoops(); + for (int ii = 0; ii < fCurveLoops.Count; ii++) + { + double grArea = ExporterIFCUtils.ComputeAreaOfCurveLoops(new List() { fCurveLoops[ii] }); + if (grArea > largestFaceGrossArea) + largestFaceGrossArea = grArea; + } + grossArea += largestFaceGrossArea; + } } - return null; - } + netArea = UnitUtil.ScaleArea(netArea); + grossArea = UnitUtil.ScaleArea(grossArea); + volume = UnitUtil.ScaleVolume(volume); - public static IFCAnyHandle CreatePlanarForcePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) - { + if (scaledDepth > MathUtil.Eps() && !MathUtil.IsAlmostZero(scaledWidth) && !MathUtil.IsAlmostZero(grossArea)) + { + double grossVolume = UnitUtil.ScaleVolume(UnitUtil.UnscaleLength(scaledWidth) * UnitUtil.UnscaleArea(grossArea)); + IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityVolume(file, "GrossVolume", null, null, grossVolume); + quantityHnds.Add(quantityHnd); + } - IFCAnyHandle propHnd = CreateDoublePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, - "IfcPlanarForceMeasure", SpecTypeId.AreaForce, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; + if (!MathUtil.IsAlmostZero(grossArea)) + { + IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityArea(file, "GrossSideArea", null, null, grossArea); + quantityHnds.Add(quantityHnd); + } - if (revitBuiltInParam != BuiltInParameter.INVALID) + if (!MathUtil.IsAlmostZero(netArea)) { - string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateDoublePropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, - "IfcPlanarForceMeasure", SpecTypeId.AreaForce, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; + IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityArea(file, "NetSideArea", null, null, netArea); + quantityHnds.Add(quantityHnd); } - return null; - } + if (!MathUtil.IsAlmostZero(volume)) + { + IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityVolume(file, "NetVolume", null, null, volume); + quantityHnds.Add(quantityHnd); + } - /// Create a PlanarForceMeasure property. - /// The IFC file. - /// The name of the property. - /// The value of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreatePlanarForceProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) - { - IFCData planarForceData = IFCDataUtil.CreateAsPlanarForceMeasure(value); - return CreateCommonProperty(file, propertyName, planarForceData, valueType, null); + string quantitySetName = string.Empty; + if (ExporterCacheManager.ExportOptionsCache.ExportAs4) + { + quantitySetName = "Qto_WallBaseQuantities"; + } + + CreateAndRelateBaseQuantities(file, exporterIFC, wallHnd, quantityHnds, quantitySetName); } - /// Create a PowerMeasure property. - /// The IFC file. - /// The name of the property. - /// The value of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreatePowerProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) + /// + /// Creates and relate base quantities to quantity handle. + /// + /// The file. + /// The exporter. + /// The element handle. + /// The quantity handles. + static public void CreateAndRelateBaseQuantities(IFCFile file, ExporterIFC exporterIFC, IFCAnyHandle elemHnd, HashSet quantityHnds, + string quantitySetName = null, string description = null, string methodOfMeasurement = null) { - IFCData powerData = IFCDataUtil.CreateAsPowerMeasure(value); - return CreateCommonProperty(file, propertyName, powerData, valueType, null); + if (quantityHnds.Count > 0) + { + if (string.IsNullOrEmpty(quantitySetName)) + quantitySetName = "BaseQuantities"; + IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; + + // Skip if the elementHandle has the associated QuantitySet has been created before + if (!ExporterCacheManager.QtoSetCreated.Contains((elemHnd, quantitySetName))) + { + string quantityGuid = GUIDUtil.GenerateIFCGuidFrom( + GUIDUtil.CreateGUIDString(IFCEntityType.IfcElementQuantity, quantitySetName, elemHnd)); + IFCAnyHandle quantity = IFCInstanceExporter.CreateElementQuantity(file, elemHnd, + quantityGuid, ownerHistory, quantitySetName, description, + methodOfMeasurement, quantityHnds); + HashSet relatedObjects = new HashSet(); + relatedObjects.Add(elemHnd); + + string quantityRelGuid = GUIDUtil.GenerateIFCGuidFrom( + GUIDUtil.CreateGUIDString(IFCEntityType.IfcRelDefinesByProperties, quantitySetName, elemHnd)); + ExporterUtil.CreateRelDefinesByProperties(file, quantityRelGuid, ownerHistory, null, null, + relatedObjects, quantity); + } + } } - /// Create a ThermalTransmittance property. - /// The IFC file. - /// The name of the property. - /// The value of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateThermalTransmittanceProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) + /// + /// Creates the shared beam, column and member QTO values. + /// + /// The exporter. + /// The element handle. + /// The element. + /// The IFCExportBodyParams containing the appropriate data. + public static void CreateBeamColumnMemberBaseQuantities(ExporterIFC exporterIFC, IFCAnyHandle elemHandle, Element element, IFCExportBodyParams ecData) { - IFCData thermalTransmittanceData = IFCDataUtil.CreateAsThermalTransmittanceMeasure(value); - return CreateCommonProperty(file, propertyName, thermalTransmittanceData, valueType, null); + FamilyTypeInfo ifcTypeInfo = new FamilyTypeInfo() { extraParams = ecData }; + CreateBeamColumnBaseQuantities(exporterIFC, elemHandle, element, ifcTypeInfo, null); } - /// Create a VolumetricFlowRate property. - /// The IFC file. - /// The name of the property. - /// The value of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateVolumetricFlowRateMeasureProperty(IFCFile file, string propertyName, double value, PropertyValueType valueType) + /// + /// True if QTO width and length values should be reversed. + /// + /// The element handle. + public static bool IsWidthLengthReversed(IFCAnyHandle elemHandle) { - IFCData volumetricFlowRateData = IFCDataUtil.CreateAsVolumetricFlowRateMeasure(value); - return CreateCommonProperty(file, propertyName, volumetricFlowRateData, valueType, null); + return (IFCAnyHandleUtil.IsSubTypeOf(elemHandle, IFCEntityType.IfcSlab) || IFCAnyHandleUtil.IsSubTypeOf(elemHandle, IFCEntityType.IfcCovering)); } /// - /// Create a VolumetricFlowRate measure property from the element's parameter. + /// Creates property sets for Revit groups and parameters, if export options is set. /// - /// The IFC file. /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateVolumetricFlowRatePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) + /// The Element. + /// The collection of IFCAnyHandles to relate properties to. + /// Forces properties creation even if 'Export internal properties' is unchecked. + public static void CreateInternalRevitPropertySets(ExporterIFC exporterIFC, Element element, + ISet elementSets, bool forceCreate) { - return CreateDoublePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, - "IfcVolumetricFlowRateMeasure", SpecTypeId.AirFlow, valueType); - } + if (exporterIFC == null || element == null || + (!ExporterCacheManager.ExportOptionsCache.PropertySetOptions.ExportInternalRevit && !forceCreate)) + return; - /// - /// Create a Time measure property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateTimePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) - { - return CreateDoublePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, - "IfcTimeMeasure", SpecTypeId.Time, valueType); - } + // We will allow creating internal Revit property sets for element types with no associated element handles. + if (((elementSets?.Count ?? 0) == 0) && !(element is ElementType)) + return; - /// - /// Create a Sound power measure property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateSoundPowerPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) - { - double propertyValue; - Parameter param = ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue); - if (param != null) - { - if (!ParameterUtil.ParameterDataTypeIsEqualTo(param, SpecTypeId.Number)) - propertyValue = UnitUtil.ScaleSoundPower(propertyValue); + IFCFile file = exporterIFC.GetFile(); - if (valueType == PropertyValueType.BoundedValue) - { - IList boundedData = GetBoundedDataFromElement(elem, revitParameterName, propertyValue, SpecTypeId.Wattage, "IfcSoundPowerMeasure"); - return CreateBoundedValuePropertyFromList(file, ifcPropertyName, boundedData, null); - } - else - { - return CreateSoundPowerMeasureProperty(file, ifcPropertyName, propertyValue, valueType); - } + ElementId typeId = element.GetTypeId(); + Element elementType = element.Document.GetElement(typeId); + int whichStart = elementType != null ? 0 : (element is ElementType ? 1 : 0); + if (whichStart == 1) + { + typeId = element.Id; + elementType = element as ElementType; } - return null; - } - /// - /// Create a Sound pressure measure property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateSoundPressurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) - { - double propertyValue; - Parameter param = ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue); - if (param != null) + SortedDictionary)>[] propertySets; + propertySets = new SortedDictionary)>[2]; + propertySets[0] = new SortedDictionary)>(); + propertySets[1] = new SortedDictionary)>(); + + // pass through: element and element type. If the element is a ElementType, there will only be one pass. + for (int which = whichStart; which < 2; which++) { - if (!ParameterUtil.ParameterDataTypeIsEqualTo(param, SpecTypeId.Number)) - propertyValue = UnitUtil.ScaleSoundPressure(propertyValue); + Element whichElement = (which == 0) ? element : elementType; + if (whichElement == null) + continue; + + // If we have already processed this element, just add the new + // IFC entities. + if (ExporterCacheManager.CreatedInternalPropertySets.TryAppend(whichElement.Id, elementSets)) + continue; - if (valueType == PropertyValueType.BoundedValue) + ElementId whichElementId = whichElement.Id; + + bool createType = (which == 1); + if (createType) { - IList boundedData = GetBoundedDataFromElement(elem, revitParameterName, propertyValue, SpecTypeId.HvacPressure, "IfcSoundPressureMeasure"); - return CreateBoundedValuePropertyFromList(file, ifcPropertyName, boundedData, null); + if (ExporterCacheManager.TypePropertyInfoCache.HasTypeProperties(typeId)) + continue; } - else + + IDictionary parameterElementCache = + ParameterUtil.GetNonIFCParametersForElement(whichElementId); + if (parameterElementCache == null) + continue; + + foreach (KeyValuePair parameterElementGroup in parameterElementCache) { - return CreateSoundPressureMeasureProperty(file, ifcPropertyName, propertyValue, valueType); + ForgeTypeId parameterGroup = new ForgeTypeId(parameterElementGroup.Key); + string groupName = LabelUtils.GetLabelForGroup(parameterGroup); + + // We are only going to append the "(Type)" suffix if we aren't also exporting the corresponding entity type. + // In general, we'd like to always export them entity type, regardles of whether it holds any geometry or not - it can hold + // at least the parameteric information. When this is acheived, when can get rid of this entirely. + // Unfortunately, IFC2x3 doesn't have types for all entities, so for IFC2x3 at least this will continue to exist + // in some fashion. + // There was a suggestion in SourceForge that we could "merge" the instance/type property sets in the cases where we aren't + // creating an entity type, and in the cases where two properties had the same name, use the instance over type. + // However, given our intention to generally export all types, this seems like a lot of work for diminishing returns. + if (whichElement is ElementType) + if (which == 1 && !ExporterCacheManager.ElementTypeToHandleCache.IsRegistered(whichElement as ElementType)) + groupName += Properties.Resources.PropertySetTypeSuffix; + + HashSet currPropertiesForGroup = new HashSet(); + propertySets[which][parameterElementGroup.Key] = (groupName, currPropertiesForGroup); + + foreach (Parameter parameter in parameterElementGroup.Value.ParameterCache.Values) + { + if (!parameter.HasValue) + continue; + + Definition parameterDefinition = parameter.Definition; + if (parameterDefinition == null) + continue; + + string parameterCaption = parameterDefinition.Name; + + switch (parameter.StorageType) + { + case StorageType.None: + break; + case StorageType.Integer: + { + int value = parameter.AsInteger(); + string valueAsString = parameter.AsValueString(); + + // YesNo or actual integer? + if (parameterDefinition.GetDataType() == SpecTypeId.Boolean.YesNo) + { + currPropertiesForGroup.Add(CreateBooleanPropertyFromCache(file, parameterCaption, value != 0, PropertyValueType.SingleValue)); + } + else if (parameterDefinition.GetDataType().Empty() && (valueAsString != null)) + { + // This is probably an internal enumerated type that should be exported as a string. + currPropertiesForGroup.Add(CreateIdentifierPropertyFromCache(file, parameterCaption, valueAsString, PropertyValueType.SingleValue)); + } + else + { + currPropertiesForGroup.Add(CreateIntegerPropertyFromCache(file, parameterCaption, value, PropertyValueType.SingleValue)); + } + break; + } + case StorageType.Double: + { + double value = parameter.AsDouble(); + IFCAnyHandle propertyHandle = CreateRealPropertyBasedOnParameterType(file, parameter, parameterCaption, value, PropertyValueType.SingleValue); + + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propertyHandle)) + currPropertiesForGroup.Add(propertyHandle); + break; + } + case StorageType.String: + { + string value = parameter.AsString(); + if (!string.IsNullOrEmpty(value)) + currPropertiesForGroup.Add(CreateTextPropertyFromCache(file, parameterCaption, value, PropertyValueType.SingleValue)); + break; + } + case StorageType.ElementId: + { + if (parameter.AsElementId() != ElementId.InvalidElementId) + { + string valueString = parameter.AsValueString(); + currPropertiesForGroup.Add(CreateLabelPropertyFromCache(file, parameter.Id, parameterCaption, valueString, PropertyValueType.SingleValue, true, null)); + } + break; + } + } + } } } - return null; - } - - /// - /// Create a SpecificHeat Capacity measure property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateSpecificHeatCapacityPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) - { - double propertyValue; - Parameter param = ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue); - if (param != null) + for (int which = whichStart; which < 2; which++) { - if (!ParameterUtil.ParameterDataTypeIsEqualTo(param, SpecTypeId.Number)) - propertyValue = UnitUtil.ScaleSpecificHeatCapacity(propertyValue); + Element whichElement = (which == 0) ? element : elementType; + if (whichElement == null) + continue; + + HashSet createdPropertySets = new HashSet(); - if (valueType == PropertyValueType.BoundedValue) + int size = propertySets[which].Count; + if (size == 0) { - IList boundedData = GetBoundedDataFromElement(elem, revitParameterName, propertyValue, SpecTypeId.SpecificHeat, "IfcSpecificHeatCapacityMeasure"); - return CreateBoundedValuePropertyFromList(file, ifcPropertyName, boundedData, null); + ExporterCacheManager.TypePropertyInfoCache.AddNewElementHandles(typeId, elementSets); + continue; } - else + + bool materialProperties = element is Material; + foreach (KeyValuePair)> currPropertySet in propertySets[which]) { - return CreateSpecificHeatCapacityMeasureProperty(file, ifcPropertyName, propertyValue, valueType); - } - } - return null; - } + if (currPropertySet.Value.Item2.Count == 0) + continue; - /// - /// Create a Dynamic Viscosity measure property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateDynamicViscosityPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) - { - double propertyValue; - Parameter param = ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue); - if (param != null) - { - if (!ParameterUtil.ParameterDataTypeIsEqualTo(param, SpecTypeId.Number)) - propertyValue = UnitUtil.ScaleDynamicViscosity(propertyValue); + if (materialProperties) + { + MaterialPropertiesUtil.ExportGenericMaterialPropertySet(file, elementSets?.ToList().First(), currPropertySet.Value.Item2, null, currPropertySet.Value.Item1); + } + else + { + string psetGUID = GUIDUtil.GenerateIFCGuidFrom( + GUIDUtil.CreateGUIDString(whichElement, "IfcPropertySet: " + currPropertySet.Key.ToString())); - if (valueType == PropertyValueType.BoundedValue) - { - IList boundedData = GetBoundedDataFromElement(elem, revitParameterName, propertyValue, SpecTypeId.HvacViscosity, "IfcDynamicViscosityMeasure"); - return CreateBoundedValuePropertyFromList(file, ifcPropertyName, boundedData, null); + IFCAnyHandle propertySet = IFCInstanceExporter.CreatePropertySet(file, psetGUID, + ExporterCacheManager.OwnerHistoryHandle, currPropertySet.Value.Item1, null, + currPropertySet.Value.Item2); + createdPropertySets.Add(propertySet); + } } - else + + // Don't need to create relations for material properties + if (!materialProperties) { - return CreateDynamicViscosityMeasureProperty(file, ifcPropertyName, propertyValue, valueType); + if (which == 0) + ExporterCacheManager.CreatedInternalPropertySets.Add(whichElement.Id, createdPropertySets, elementSets); + else + ExporterCacheManager.TypePropertyInfoCache.AddNewTypeProperties(typeId, createdPropertySets, elementSets); } } - return null; } /// - /// Create an friction loss custom measure property from the element's parameter. + /// Get a unit type of parameter. + /// IFCUnit for each one. /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The name of the property. Also, the backup name of the parameter. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateElectricalResistivityPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) - { - double propertyValue; - Parameter param = ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue); - if (param != null) - { - if (!ParameterUtil.ParameterDataTypeIsEqualTo(param, SpecTypeId.Number)) - propertyValue = UnitUtil.ScaleDouble(SpecTypeId.ElectricalResistivity, propertyValue); - - if (valueType == PropertyValueType.BoundedValue) - { - IList boundedData = GetBoundedDataFromElement(elem, revitParameterName, propertyValue, SpecTypeId.ElectricalResistivity, "IfcReal"); - return CreateBoundedValuePropertyFromList(file, ifcPropertyName, boundedData, "ELECTRICALRESISTIVITY"); - } - else - { - return CreateElectricalResistivityPropertyFromValue(file, ifcPropertyName, propertyValue); - } - } - return null; - } - - public static IFCAnyHandle CreateElectricalResistivityPropertyFromValue(IFCFile file, string ifcPropertyName, double propertyValue) + /// The parameter. + /// The parameter unit type. + public static ForgeTypeId GetParameterUnitType(Parameter parameter) { - IFCData electricalEfficacyData = IFCDataUtil.CreateAsMeasure(propertyValue, "IfcReal"); - return CreateCommonProperty(file, ifcPropertyName, electricalEfficacyData, - PropertyValueType.SingleValue, "ELECTRICALRESISTIVITY"); - } + ForgeTypeId parameterUnitType = null; - /// - /// Create an friction loss custom measure property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The name of the property. Also, the backup name of the parameter. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateFrictionLossPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) - { - double propertyValue; - Parameter param = ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue); - if (param != null) + try { - if (!ParameterUtil.ParameterDataTypeIsEqualTo(param, SpecTypeId.Number)) - propertyValue = UnitUtil.ScaleDouble(SpecTypeId.HvacFriction, propertyValue); - - if (valueType == PropertyValueType.BoundedValue) - { - IList boundedData = GetBoundedDataFromElement(elem, revitParameterName, propertyValue, SpecTypeId.HvacFriction, "IfcReal"); - return CreateBoundedValuePropertyFromList(file, ifcPropertyName, boundedData, "FRICTIONLOSS"); - } - else - { - return CreateFrictionLossPropertyFromValue(file, ifcPropertyName, propertyValue); - } + parameterUnitType = parameter?.GetUnitTypeId(); } - return null; - } - - public static IFCAnyHandle CreateFrictionLossPropertyFromValue(IFCFile file, string ifcPropertyName, double propertyValue) - { - IFCData electricalEfficacyData = IFCDataUtil.CreateAsMeasure(propertyValue, "IfcReal"); - return CreateCommonProperty(file, ifcPropertyName, electricalEfficacyData, - PropertyValueType.SingleValue, "FRICTIONLOSS"); - } - - /// - /// Create a Color Temperature measure property from the element's parameter. This will be an IfcReal with a custom unit. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The name of the property. Also, the backup name of the parameter. - /// The created property handle. - public static IFCAnyHandle CreateColorTemperaturePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName) - { - double propertyValue; - Parameter param = ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue); - if (param != null) + catch { - if (!ParameterUtil.ParameterDataTypeIsEqualTo(param, SpecTypeId.Number)) - propertyValue = UnitUtil.ScaleDouble(SpecTypeId.ColorTemperature, propertyValue); - return CreateColorTemperaturePropertyFromValue(file, ifcPropertyName, propertyValue); + // GetUnitTypeId() can fail for reasons that don't seem to be knowable in + // advance, so we won't scale value in these cases. } - return null; - } - public static IFCAnyHandle CreateColorTemperaturePropertyFromValue(IFCFile file, string ifcPropertyName, double propertyValue) - { - IFCData colorTemperatureData = IFCDataUtil.CreateAsMeasure(propertyValue, "IfcReal"); - return CreateCommonProperty(file, ifcPropertyName, colorTemperatureData, - PropertyValueType.SingleValue, "COLORTEMPERATURE"); + return parameterUnitType; } /// - /// Create an electrical efficacy custom measure property from the element's parameter. + /// Creates property from real parameter. + /// There are many different ParameterTypes in Revit that share the same unit dimensions, but that + /// have potentially different display units (e.g. Bar Diameter could be in millimeters while the project + /// default length parameter is in meters.) For now, we will only support one unit type. At a later + /// point, we could decide to have different caches for each parameter type, and export a different + /// IFCUnit for each one. /// /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The name of the property. Also, the backup name of the parameter. + /// The parameter. + /// The name of the property. + /// The value of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateElectricalEfficacyPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateRealPropertyBasedOnParameterType(IFCFile file, Parameter parameter, string propertyName, double propertyValue, PropertyValueType valueType) { - double propertyValue; - Parameter param = ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue); - if (param != null) - { - if (!ParameterUtil.ParameterDataTypeIsEqualTo(param, SpecTypeId.Number)) - propertyValue = UnitUtil.ScaleDouble(SpecTypeId.Efficacy, propertyValue); + if (parameter == null) + return null; - if (valueType == PropertyValueType.BoundedValue) - { - IList boundedData = GetBoundedDataFromElement(elem, revitParameterName, propertyValue, SpecTypeId.Efficacy, "IfcReal"); - return CreateBoundedValuePropertyFromList(file, ifcPropertyName, boundedData, "LUMINOUSEFFICACY"); - } - else - { - return CreateElectricalEfficacyPropertyFromValue(file, ifcPropertyName, propertyValue); - } - } - return null; - } + ForgeTypeId type = parameter.Definition?.GetDataType(); + ForgeTypeId fallbackUnitType = GetParameterUnitType(parameter); - public static IFCAnyHandle CreateElectricalEfficacyPropertyFromValue(IFCFile file, string ifcPropertyName, double propertyValue) - { - IFCData electricalEfficacyData = IFCDataUtil.CreateAsMeasure(propertyValue, "IfcReal"); - return CreateCommonProperty(file, ifcPropertyName, electricalEfficacyData, - PropertyValueType.SingleValue, "LUMINOUSEFFICACY"); + return CreateRealPropertyByType(file, type, propertyName, propertyValue, valueType, fallbackUnitType); } /// - /// Create a currency measure property from the element's parameter. + /// Creates property from real parameter. /// /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The name of the property. Also, the backup name of the parameter. + /// The type of the parameter. + /// The name of the property. + /// The value of the property. /// The value type of the property. + /// The optional unit type. Can be used for scaling in final case /// The created property handle. - public static IFCAnyHandle CreateCurrencyPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateRealPropertyByType(IFCFile file, ForgeTypeId parameterType, string propertyName, double propertyValue, PropertyValueType valueType, ForgeTypeId fallbackUnitType = null) { - double propertyValue; - if (ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue) != null) + IFCAnyHandle propertyHandle = null; + + if (parameterType == SpecTypeId.Acceleration) { - string measureName = ExporterCacheManager.UnitsCache.ContainsKey("CURRENCY") ? "IfcMonetaryMeasure" : "IfcReal"; - if (valueType == PropertyValueType.BoundedValue) - { - IList boundedData = GetBoundedDataFromElement(elem, revitParameterName, propertyValue, SpecTypeId.Number, measureName); - return CreateBoundedValuePropertyFromList(file, ifcPropertyName, boundedData, null); - } - else - { - IFCData currencyData = IFCDataUtil.CreateAsMeasure(propertyValue, measureName); - return CreateCommonProperty(file, ifcPropertyName, currencyData, PropertyValueType.SingleValue, null); - } + double scaledValue = UnitUtil.ScaleAcceleration(propertyValue); + propertyHandle = CreateAccelerationPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); } - return null; - } - - /// - /// Create a ThermodynamicTemperature measure property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The name of the property. Also, the backup name of the parameter. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateThermodynamicTemperaturePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) - { - double propertyValue; - Parameter param = ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue); - if (param != null) + else if (parameterType == SpecTypeId.Energy || + parameterType == SpecTypeId.HvacEnergy) { - if (!ParameterUtil.ParameterDataTypeIsEqualTo(param, SpecTypeId.Number)) - propertyValue = UnitUtil.ScaleThermodynamicTemperature(propertyValue); - - if (valueType == PropertyValueType.BoundedValue) - { - IList boundedData = GetBoundedDataFromElement(elem, revitParameterName, propertyValue, SpecTypeId.HvacTemperature, "IfcThermodynamicTemperatureMeasure"); - return CreateBoundedValuePropertyFromList(file, ifcPropertyName, boundedData, null); - } - else - { - return CreateThermodynamicTemperaturePropertyFromCache(file, ifcPropertyName, propertyValue, valueType); - } + double scaledValue = UnitUtil.ScaleEnergy(propertyValue); + propertyHandle = CreateEnergyPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); } - - param = ParameterUtil.GetDoubleValueFromElement(elem, ifcPropertyName, out propertyValue); - if (param != null) + else if (parameterType == SpecTypeId.LinearMoment) { - if (!ParameterUtil.ParameterDataTypeIsEqualTo(param, SpecTypeId.Number)) - propertyValue = UnitUtil.ScaleThermodynamicTemperature(propertyValue); - - if (valueType == PropertyValueType.BoundedValue) - { - IList boundedData = GetBoundedDataFromElement(elem, ifcPropertyName, propertyValue, SpecTypeId.HvacTemperature, "IfcThermodynamicTemperatureMeasure"); - return CreateBoundedValuePropertyFromList(file, ifcPropertyName, boundedData, null); - } - else - { - return CreateThermodynamicTemperaturePropertyFromCache(file, ifcPropertyName, propertyValue, valueType); - } + double scaledValue = UnitUtil.ScaleLinearMoment(propertyValue); + propertyHandle = CreateLinearMomentPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); } - return null; - } - - /// - /// Create a friction loss property from the element's parameter. This will be an IfcReal with a special temperature unit. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateFrictionLossPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) - { - IFCAnyHandle propHnd = CreateFrictionLossPropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; - - if (revitBuiltInParam != BuiltInParameter.INVALID) + else if (parameterType == SpecTypeId.MassPerUnitLength || + parameterType == SpecTypeId.PipeMassPerUnitLength) { - string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateFrictionLossPropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; + double scaledValue = UnitUtil.ScaleMassPerLength(propertyValue); + propertyHandle = CreateMassPerLengthPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); } - - return null; - - } - /// - /// Create a electrical resistivity property from the element's parameter. This will be an IfcReal with a special temperature unit. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateElectricalResistivityPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) - { - IFCAnyHandle propHnd = CreateElectricalResistivityPropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; - - if (revitBuiltInParam != BuiltInParameter.INVALID) + else if (parameterType == SpecTypeId.Moment) { - string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateElectricalResistivityPropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; + double scaledValue = UnitUtil.ScaleTorque(propertyValue); + propertyHandle = CreateTorquePropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); } - - return null; - } - - /// - /// Create a color temperature property from the element's parameter. This will be an IfcReal with a special temperature unit. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateColorTemperaturePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) - { - IFCAnyHandle propHnd = CreateColorTemperaturePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; - - if (revitBuiltInParam != BuiltInParameter.INVALID) + else if (parameterType == SpecTypeId.PointSpringCoefficient) { - string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateColorTemperaturePropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; + double scaledValue = UnitUtil.ScaleLinearStiffness(propertyValue); + propertyHandle = CreateLinearStiffnessPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); } - - return null; - } - - /// - /// Create an electrical efficacy custom property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateElectricalEfficacyPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) - { - IFCAnyHandle propHnd = CreateElectricalEfficacyPropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; - - if (revitBuiltInParam != BuiltInParameter.INVALID) + else if (parameterType == SpecTypeId.Pulsation) { - string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateElectricalEfficacyPropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; + double scaledValue = UnitUtil.ScaleAngularVelocity(propertyValue); + propertyHandle = CreateAngularVelocityPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); } - - return null; - } - - /// - /// Create a currency property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateCurrencyPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) - { - IFCAnyHandle propHnd = CreateCurrencyPropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; - - if (revitBuiltInParam != BuiltInParameter.INVALID) + else if (parameterType == SpecTypeId.ThermalResistance) { - string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateCurrencyPropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; + double scaledValue = UnitUtil.ScaleThermalResistance(propertyValue); + propertyHandle = CreateThermalResistancePropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); } - - return null; - } - - /// - /// Create a ThermodynamicTemperature measure property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateThermodynamicTemperaturePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) - { - IFCAnyHandle propHnd = CreateThermodynamicTemperaturePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; - - if (revitBuiltInParam != BuiltInParameter.INVALID) + else if (parameterType == SpecTypeId.WarpingConstant) { - string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateThermodynamicTemperaturePropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; + double scaledValue = UnitUtil.ScaleWarpingConstant(propertyValue); + propertyHandle = CreateWarpingConstantPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); } - - return null; - } - - /// - /// Create a VolumetricFlowRate measure property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateVolumetricFlowRatePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) - { - IFCAnyHandle propHnd = CreateVolumetricFlowRatePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; - - if (revitBuiltInParam != BuiltInParameter.INVALID) + else if (parameterType == SpecTypeId.Angle || + parameterType == SpecTypeId.Rotation || + parameterType == SpecTypeId.RotationAngle) { - string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateVolumetricFlowRatePropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; + double scaledValue = UnitUtil.ScaleAngle(propertyValue); + propertyHandle = CreatePlaneAnglePropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); } - - return null; - } - - /// - /// Create a Time property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateTimePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) - { - IFCAnyHandle propHnd = CreateTimePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; - - if (revitBuiltInParam != BuiltInParameter.INVALID) + else if (parameterType == SpecTypeId.Slope || + parameterType == SpecTypeId.HvacSlope || + parameterType == SpecTypeId.PipingSlope || + parameterType == SpecTypeId.DemandFactor || + parameterType == SpecTypeId.Factor) { - string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateTimePropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; + propertyHandle = CreatePositiveRatioPropertyFromCache(file, propertyName, + new List() { propertyValue }, valueType, null); } - - return null; - } - - /// - /// Create a Sound power property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateSoundPowerPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) - { - IFCAnyHandle propHnd = CreateSoundPowerPropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; - - if (revitBuiltInParam != BuiltInParameter.INVALID) + else if (parameterType == SpecTypeId.Area || + parameterType == SpecTypeId.CrossSection || + parameterType == SpecTypeId.ReinforcementArea || + parameterType == SpecTypeId.SectionArea) { - string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateSoundPowerPropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; + double scaledValue = UnitUtil.ScaleArea(propertyValue); + propertyHandle = CreateAreaPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); } - - return null; - } - - /// - /// Create a Sound pressure property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateSoundPressurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) - { - IFCAnyHandle propHnd = CreateSoundPressurePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; - - if (revitBuiltInParam != BuiltInParameter.INVALID) + else if (parameterType == SpecTypeId.BarDiameter || + parameterType == SpecTypeId.CrackWidth || + parameterType == SpecTypeId.Displacement || + parameterType == SpecTypeId.Distance || + parameterType == SpecTypeId.CableTraySize || + parameterType == SpecTypeId.ConduitSize || + parameterType == SpecTypeId.Length || + parameterType == SpecTypeId.DuctInsulationThickness || + parameterType == SpecTypeId.DuctLiningThickness || + parameterType == SpecTypeId.DuctSize || + parameterType == SpecTypeId.HvacRoughness || + parameterType == SpecTypeId.PipeDimension || + parameterType == SpecTypeId.PipeInsulationThickness || + parameterType == SpecTypeId.PipeSize || + parameterType == SpecTypeId.PipingRoughness || + parameterType == SpecTypeId.ReinforcementCover || + parameterType == SpecTypeId.ReinforcementLength || + parameterType == SpecTypeId.ReinforcementSpacing || + parameterType == SpecTypeId.SectionDimension || + parameterType == SpecTypeId.SectionProperty || + parameterType == SpecTypeId.WireDiameter || + parameterType == SpecTypeId.SurfaceAreaPerUnitLength) { - string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateSoundPressurePropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; + double scaledValue = UnitUtil.ScaleLength(propertyValue); + propertyHandle = CreateLengthPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); } - - return null; - } - - /// - /// Create a Specific Heat Capacity property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateSpecificHeatCapacityPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) - { - IFCAnyHandle propHnd = CreateSpecificHeatCapacityPropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; - - if (revitBuiltInParam != BuiltInParameter.INVALID) + else if (parameterType == SpecTypeId.Currency) { - string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateSpecificHeatCapacityPropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; + IFCData currencyData = ExporterCacheManager.UnitsCache.ContainsKey("CURRENCY") ? + IFCDataUtil.CreateAsMonetaryMeasure(propertyValue) : + IFCDataUtil.CreateAsReal(propertyValue); + propertyHandle = CreateCommonProperty(file, propertyName, currencyData, + valueType, null); } - - return null; - } - - /// - /// Create a Dynamic Viscosity property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateDynamicViscosityPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) - { - IFCAnyHandle propHnd = CreateDynamicViscosityPropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; - - if (revitBuiltInParam != BuiltInParameter.INVALID) + else if (parameterType == SpecTypeId.ApparentPower || + parameterType == SpecTypeId.ElectricalPower || + parameterType == SpecTypeId.Wattage || + parameterType == SpecTypeId.CoolingLoad || + parameterType == SpecTypeId.HeatGain || + parameterType == SpecTypeId.HeatingLoad || + parameterType == SpecTypeId.HvacPower) { - string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateDynamicViscosityPropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; + double scaledValue = UnitUtil.ScalePower(propertyValue); + propertyHandle = CreatePowerPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); } - - return null; - } - - /// - /// Create an IfcClassificationReference property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The name of the property. - /// The created property handle. - public static IFCAnyHandle CreateClassificationReferencePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName) - { - if (elem == null) - return null; - - string propertyValue; - if (ParameterUtil.GetStringValueFromElement(elem, revitParameterName, out propertyValue) != null) - return CreateClassificationReferenceProperty(file, ifcPropertyName, propertyValue); - - return null; - } - - /// - /// Create a generic measure property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The name of the property. - /// The IfcMeasure type of the property. - /// Identifier of the property spec. - /// The property value type of the property. - /// The created property handle. - private static IFCAnyHandle CreateDoublePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, string measureType, ForgeTypeId specTypeId, PropertyValueType valueType) - { - double propertyValue; - Parameter param = ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue); - if (param != null) + else if (parameterType == SpecTypeId.Current) { - if (!ParameterUtil.ParameterDataTypeIsEqualTo(param, SpecTypeId.Number)) - propertyValue = UnitUtil.ScaleDouble(specTypeId, propertyValue); - - if (valueType == PropertyValueType.BoundedValue) - { - IList boundedData = GetBoundedDataFromElement(elem, revitParameterName, propertyValue, specTypeId, measureType); - return CreateBoundedValuePropertyFromList(file, ifcPropertyName, boundedData, null); - } - else - { - IFCData doubleData = IFCDataUtil.CreateAsMeasure(propertyValue, measureType); - return CreateCommonProperty(file, ifcPropertyName, doubleData, valueType, null); - } + double scaledValue = UnitUtil.ScaleElectricCurrent(propertyValue); + propertyHandle = CreateElectricCurrentPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); } - return null; - } - - /// - /// Create a list of bounded data. - /// - /// The Element. - /// The name of the parameter. - /// The SetPoint value. - /// Identifier of the property spec. - /// The IfcMeasure type of the property. - /// List of bounded data. Null if unset. - public static IList GetBoundedDataFromElement(Element elem, string revitParameterName, double propertyValue, ForgeTypeId specTypeId, string measureType) - { - IList boundedData = new List(); - - IList boundedValues = GetBoundedValuesFromElement(elem, revitParameterName, specTypeId); - boundedValues.Insert(0, propertyValue); - foreach (double? val in boundedValues) + else if (parameterType == SpecTypeId.Diffusivity) { - if (!val.HasValue) - boundedData.Add(null); - else - boundedData.Add(IFCDataUtil.CreateAsMeasure(val.Value, measureType)); + double scaledValue = UnitUtil.ScaleMoistureDiffusivity(propertyValue); + propertyHandle = CreateMoistureDiffusivityPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); } - return boundedData; - } - - /// - /// Reads bounded values from element - /// - /// The Element. - /// The name of the parameter. - /// Identifier of the property spec. - /// List of bounded values. Null if unset. - public static IList GetBoundedValuesFromElement(Element elem, string revitParameterName, ForgeTypeId specTypeId) - { - IList boundedValues = new List(); - - double upperBound; - Parameter param = ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName + ".UpperBoundValue", out upperBound); - if (param != null) + else if (parameterType == SpecTypeId.ElectricalFrequency || + parameterType == SpecTypeId.StructuralFrequency) { - if (!ParameterUtil.ParameterDataTypeIsEqualTo(param, SpecTypeId.Number)) - boundedValues.Add(UnitUtil.ScaleDouble(specTypeId, upperBound)); + propertyHandle = CreateFrequencyPropertyFromCache(file, propertyName, + new List() { propertyValue }, valueType, null); } - else + else if (parameterType == SpecTypeId.Illuminance) { - boundedValues.Add(null); + double scaledValue = UnitUtil.ScaleIlluminance(propertyValue); + propertyHandle = CreateIlluminancePropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); } - - double lowerBound; - param = ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName + ".LowerBoundValue", out lowerBound); - if (param != null) + else if (parameterType == SpecTypeId.LuminousFlux) { - if (!ParameterUtil.ParameterDataTypeIsEqualTo(param, SpecTypeId.Number)) - boundedValues.Add(UnitUtil.ScaleDouble(specTypeId, lowerBound)); + double scaledValue = UnitUtil.ScaleLuminousFlux(propertyValue); + propertyHandle = CreateLuminousFluxPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); } - else + else if (parameterType == SpecTypeId.LuminousIntensity) { - boundedValues.Add(null); + double scaledValue = UnitUtil.ScaleLuminousIntensity(propertyValue); + propertyHandle = CreateLuminousIntensityPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); } - - return boundedValues; - } - - /// - /// Create a Force measure property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateForcePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) - { - return CreateDoublePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, - "IfcForceMeasure", SpecTypeId.Force, valueType); - } - - /// - /// Create a Power measure property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreatePowerPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) - { - double propertyValue; - Parameter powerParam = ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue); - if (powerParam != null) + else if (parameterType == SpecTypeId.ElectricalPotential) { - // We are going to do a little hack here which we will need to extend in a nice way. The built-in parameter corresponding - // to "TotalWattage" is a string value in Revit that is likely going to be in the current units, and doesn't need to be scaled twice. - bool needToScale = !(ifcPropertyName == "TotalWattage" && powerParam.StorageType == StorageType.String) - && !ParameterUtil.ParameterDataTypeIsEqualTo(powerParam, SpecTypeId.Number); - - double scaledpropertyValue = needToScale ? UnitUtil.ScalePower(propertyValue) : propertyValue; - - if (valueType == PropertyValueType.BoundedValue) - { - IList boundedData = GetBoundedDataFromElement(elem, revitParameterName, propertyValue, - needToScale ? SpecTypeId.HvacPower : SpecTypeId.Number, "IfcPowerMeasure"); - return CreateBoundedValuePropertyFromList(file, ifcPropertyName, boundedData, null); - } - else - { - return CreatePowerPropertyFromCache(file, ifcPropertyName, scaledpropertyValue, valueType); - } + double scaledValue = UnitUtil.ScaleElectricVoltage(propertyValue); + propertyHandle = CreateElectricVoltagePropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); } - return null; - } - - /// - /// Create a Luminous flux measure property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateLuminousFluxMeasurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) - { - return CreateDoublePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, - "IfcLuminousFluxMeasure", SpecTypeId.LuminousFlux, valueType); - } - - /// - /// Create a Luminous intensity measure property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateLuminousIntensityMeasurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) - { - return CreateDoublePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, - "IfcLuminousIntensityMeasure", SpecTypeId.LuminousIntensity, valueType); - } - - /// - /// Create a illuminance measure property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateIlluminanceMeasurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) - { - return CreateDoublePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, - "IfcIlluminanceMeasure", SpecTypeId.Illuminance, valueType); - } - - /// - /// Create a heat flux density measure property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateHeatFluxDensityMeasurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) - { - return CreateDoublePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, - "IfcHeatFluxDensityMeasure", SpecTypeId.HvacPowerDensity, valueType); - } - - /// - /// Create a Mass measure property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateMassMeasurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) - { - return CreateDoublePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, - "IfcMassMeasure", SpecTypeId.Mass, valueType); - } - - /// - /// Create a pressure measure property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreatePressurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) - { - return CreateDoublePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, - "IfcPressureMeasure", SpecTypeId.HvacPressure, valueType); - } - - /// - /// Create a ThermalConductivity measure property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateThermalConductivityPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) - { - double propertyValue; - Parameter param = ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue); - if (param != null) + else if (parameterType == SpecTypeId.HvacTemperature || + parameterType == SpecTypeId.ElectricalTemperature || + parameterType == SpecTypeId.PipingTemperature) { - if (!ParameterUtil.ParameterDataTypeIsEqualTo(param, SpecTypeId.Number)) - propertyValue = UnitUtil.ScaleThermalConductivity(propertyValue); - - if (valueType == PropertyValueType.BoundedValue) - { - IList boundedData = GetBoundedDataFromElement(elem, revitParameterName, propertyValue, SpecTypeId.ThermalConductivity, "IfcThermalConductivityMeasure"); - return CreateBoundedValuePropertyFromList(file, ifcPropertyName, boundedData, null); - } - else - { - return CreateThermalConductivityMeasureProperty(file, ifcPropertyName, propertyValue, valueType); - } + double scaledValue = UnitUtil.ScaleThermodynamicTemperature(propertyValue); + propertyHandle = CreateThermodynamicTemperaturePropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); } - return null; - } - - /// - /// Create a ThermalExpansionCoefficient measure property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateThermalExpansionCoefficientPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) - { - double propertyValue; - Parameter param = ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue); - if (param != null) + else if (parameterType == SpecTypeId.HeatTransferCoefficient) { - if (!ParameterUtil.ParameterDataTypeIsEqualTo(param, SpecTypeId.Number)) - propertyValue = UnitUtil.ScaleThermalExpansionCoefficient(propertyValue); - - if (valueType == PropertyValueType.BoundedValue) - { - IList boundedData = GetBoundedDataFromElement(elem, revitParameterName, propertyValue, SpecTypeId.ThermalExpansionCoefficient, "IfcThermalExpansionCoefficientMeasure"); - return CreateBoundedValuePropertyFromList(file, ifcPropertyName, boundedData, null); - } - else - { - return CreateThermalExpansionCoefficientMeasureProperty(file, ifcPropertyName, propertyValue, valueType); - } + double scaledValue = UnitUtil.ScaleThermalTransmittance(propertyValue); + propertyHandle = CreateThermalTransmittancePropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); } - return null; - } - - /// - /// Create a ThermalTransmittance measure property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateThermalTransmittancePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) - { - double propertyValue; - Parameter param = ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue); - if (param != null) + else if (parameterType == SpecTypeId.Force || + parameterType == SpecTypeId.Weight) { - if (!ParameterUtil.ParameterDataTypeIsEqualTo(param, SpecTypeId.Number)) - propertyValue = UnitUtil.ScaleThermalTransmittance(propertyValue); - - if (valueType == PropertyValueType.BoundedValue) - { - IList boundedData = GetBoundedDataFromElement(elem, revitParameterName, propertyValue, SpecTypeId.HeatTransferCoefficient, "IfcThermalTransmittanceMeasure"); - return CreateBoundedValuePropertyFromList(file, ifcPropertyName, boundedData, null); - } - else - { - return CreateThermalTransmittancePropertyFromCache(file, ifcPropertyName, propertyValue, valueType); - } + double scaledValue = UnitUtil.ScaleForce(propertyValue); + propertyHandle = CreateForcePropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); } - return null; - } - - /// - /// Create an IfcClassificationReference property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. - /// The name of the property. - /// The created property handle. - public static IFCAnyHandle CreateClassificationReferencePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName) - { - IFCAnyHandle propHnd = CreateClassificationReferencePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; - - if (revitBuiltInParam != BuiltInParameter.INVALID) + else if (parameterType == SpecTypeId.AreaForce) { - string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateClassificationReferencePropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; + double scaledValue = UnitUtil.ScalePlanarForce(propertyValue); + propertyHandle = CreatePlanarForcePropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); } - - return null; - } - - /// - /// Create a Force measure property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateForcePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) - { - IFCAnyHandle propHnd = CreateForcePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; - - if (revitBuiltInParam != BuiltInParameter.INVALID) + else if (parameterType == SpecTypeId.LinearForce || + parameterType == SpecTypeId.WeightPerUnitLength) { - string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateForcePropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; + double scaledValue = UnitUtil.ScaleLinearForce(propertyValue); + propertyHandle = CreateLinearForcePropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); } - - return null; - } - - /// - /// Create a Power measure property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreatePowerPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) - { - IFCAnyHandle propHnd = CreatePowerPropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; - - if (revitBuiltInParam != BuiltInParameter.INVALID) + else if (parameterType == SpecTypeId.AirFlow || + parameterType == SpecTypeId.Flow) { - string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreatePowerPropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; + double scaledValue = UnitUtil.ScaleVolumetricFlowRate(propertyValue); + propertyHandle = CreateVolumetricFlowRatePropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); } - - return null; - } - - /// - /// Create a Mass measure property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateMassPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) - { - IFCAnyHandle propHnd = CreateMassMeasurePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; - - if (revitBuiltInParam != BuiltInParameter.INVALID) + else if (parameterType == SpecTypeId.HvacPressure || + parameterType == SpecTypeId.PipingPressure || + parameterType == SpecTypeId.Stress) { - string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateMassMeasurePropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; + double scaledValue = UnitUtil.ScalePressure(propertyValue); + propertyHandle = CreatePressurePropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); } - - return null; - } - - /// - /// Create a Mass density measure property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateMassDensityPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) - { - IFCAnyHandle propHnd = CreateMassDensityPropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; - - if (revitBuiltInParam != BuiltInParameter.INVALID) + else if (parameterType == SpecTypeId.HvacVelocity || + parameterType == SpecTypeId.PipingVelocity || + parameterType == SpecTypeId.StructuralVelocity || + parameterType == SpecTypeId.Speed) { - string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateMassDensityPropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; + double scaledValue = UnitUtil.ScaleLinearVelocity(propertyValue); + propertyHandle = CreateLinearVelocityPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); } - - return null; - } - - /// - /// Create a Mass density measure property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateMassDensityPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) - { - return CreateDoublePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, - "IfcMassDensityMeasure", SpecTypeId.MassDensity, valueType); - } - - - /// - /// Create a Modulus Of Elasticity measure property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateModulusOfElasticityPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) - { - IFCAnyHandle propHnd = CreateModulusOfElasticityPropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; - - if (revitBuiltInParam != BuiltInParameter.INVALID) + else if (parameterType == SpecTypeId.Mass || + parameterType == SpecTypeId.PipingMass) { - string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateModulusOfElasticityPropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; + double scaledValue = UnitUtil.ScaleMass(propertyValue); + propertyHandle = CreateMassPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); } - - return null; - } - - /// - /// Create a Modulus Of Elasticity measure property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateModulusOfElasticityPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) - { - return CreateDoublePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, - "IfcModulusOfElasticityMeasure", SpecTypeId.Stress, valueType); - } - - /// - /// Create a Heating Value measure property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateHeatingValuePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) - { - IFCAnyHandle propHnd = CreateHeatingValuePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; - - if (revitBuiltInParam != BuiltInParameter.INVALID) + else if (parameterType == SpecTypeId.MassDensity || + parameterType == SpecTypeId.HvacDensity) { - string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateHeatingValuePropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; + double scaledValue = UnitUtil.ScaleMassDensity(propertyValue); + propertyHandle = CreateMassDensityPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); } - - return null; - } - - /// - /// Create a Heating Value measure property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateHeatingValuePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) - { - return CreateDoublePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, - "IfcHeatingValueMeasure", SpecTypeId.SpecificHeatOfVaporization, valueType); - } - - /// - /// Create a Moisture Diffusivity measure property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateMoistureDiffusivityPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) - { - IFCAnyHandle propHnd = CreateMoistureDiffusivityPropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; - - if (revitBuiltInParam != BuiltInParameter.INVALID) + else if (parameterType == SpecTypeId.PipingDensity) { - string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateMoistureDiffusivityPropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; + double scaledValue = UnitUtil.ScaleIonConcentration(propertyValue); + propertyHandle = CreateIonConcentrationPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); + } + else if (parameterType == SpecTypeId.MomentOfInertia) + { + double scaledValue = UnitUtil.ScaleMomentOfInertia(propertyValue); + propertyHandle = CreateMomentOfInertiaPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); + } + else if (parameterType == SpecTypeId.Number) + { + propertyHandle = CreateRealPropertyFromCache(file, propertyName, new List() { propertyValue }, valueType, null); + } + else if (parameterType == SpecTypeId.PipingVolume || + parameterType == SpecTypeId.ReinforcementVolume || + parameterType == SpecTypeId.SectionModulus || + parameterType == SpecTypeId.Volume) + { + double scaledValue = UnitUtil.ScaleVolume(propertyValue); + propertyHandle = CreateVolumePropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); + } + else if (parameterType == SpecTypeId.PipingMassPerTime || + parameterType == SpecTypeId.HvacMassPerTime) + { + double scaledValue = UnitUtil.ScaleMassFlowRate(propertyValue); + propertyHandle = CreateMassFlowRatePropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); + } + else if (parameterType == SpecTypeId.AngularSpeed) + { + double scaledValue = UnitUtil.ScaleRotationalFrequency(propertyValue); + propertyHandle = CreateRotationalFrequencyPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); + } + else if (parameterType == SpecTypeId.ThermalConductivity) + { + double scaledValue = UnitUtil.ScaleThermalConductivity(propertyValue); + propertyHandle = CreateThermalConductivityPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); + } + else if (parameterType == SpecTypeId.SpecificHeat) + { + double scaledValue = UnitUtil.ScaleSpecificHeatCapacity(propertyValue); + propertyHandle = CreateSpecificHeatCapacityPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); + } + else if (parameterType == SpecTypeId.Permeability) + { + double scaledValue = UnitUtil.ScaleVaporPermeability(propertyValue); + propertyHandle = CreateVaporPermeabilityPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); + } + else if (parameterType == SpecTypeId.HvacViscosity || + parameterType == SpecTypeId.PipingViscosity) + { + double scaledValue = UnitUtil.ScaleDynamicViscosity(propertyValue); + propertyHandle = CreateDynamicViscosityPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); + } + else if (parameterType == SpecTypeId.ThermalExpansionCoefficient) + { + double scaledValue = UnitUtil.ScaleThermalExpansionCoefficient(propertyValue); + propertyHandle = CreateThermalExpansionCoefficientPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); + } + else if (parameterType == SpecTypeId.SpecificHeatOfVaporization) + { + double scaledValue = UnitUtil.ScaleHeatingValue(propertyValue); + propertyHandle = CreateHeatingValuePropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); + } + else if (parameterType == SpecTypeId.IsothermalMoistureCapacity) + { + double scaledValue = UnitUtil.ScaleIsothermalMoistureCapacity(propertyValue); + propertyHandle = CreateIsothermalMoistureCapacityPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); + } + else if (parameterType == SpecTypeId.HvacPowerDensity) + { + double scaledValue = UnitUtil.ScaleHeatFluxDensity(propertyValue); + propertyHandle = CreateHeatFluxDensityPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); + } + else if (parameterType == SpecTypeId.MassPerUnitArea && !ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4) + { + double scaledValue = UnitUtil.ScaleAreaDensity(propertyValue); + propertyHandle = CreateAreaDensityPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, null); + } + else if (parameterType == SpecTypeId.Time || + parameterType == SpecTypeId.Period) + { + double scaledValue = UnitUtil.ScaleTime(propertyValue); + IFCData timeData = IFCDataUtil.CreateAsTimeMeasure(scaledValue); + propertyHandle = CreateCommonProperty(file, propertyName, timeData, + valueType, null); + } + else if (parameterType == SpecTypeId.ColorTemperature) + { + double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.ColorTemperature, propertyValue); + propertyHandle = CreateRealPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, "COLORTEMPERATURE"); + } + else if (parameterType == SpecTypeId.CostPerArea) + { + double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.CostPerArea, propertyValue); + propertyHandle = CreateRealPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, "COSTPERAREA"); + } + else if (parameterType == SpecTypeId.ApparentPowerDensity) + { + double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.ApparentPowerDensity, propertyValue); + propertyHandle = CreateRealPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, "APPARENTPOWERDENSITY"); + } + else if (parameterType == SpecTypeId.CostRateEnergy) + { + double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.CostRateEnergy, propertyValue); + propertyHandle = CreateRealPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, "COSTRATEENERGY"); + } + else if (parameterType == SpecTypeId.CostRatePower) + { + double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.CostRatePower, propertyValue); + propertyHandle = CreateRealPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, "COSTRATEPOWER"); + } + else if (parameterType == SpecTypeId.Efficacy) + { + double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.Efficacy, propertyValue); + propertyHandle = CreateRealPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, "LUMINOUSEFFICACY"); + } + else if (parameterType == SpecTypeId.Luminance) + { + double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.Luminance, propertyValue); + propertyHandle = CreateRealPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, "LUMINANCE"); + } + else if (parameterType == SpecTypeId.ElectricalPowerDensity) + { + double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.ElectricalPowerDensity, propertyValue); + propertyHandle = CreateRealPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, "ELECTRICALPOWERDENSITY"); + } + else if (parameterType == SpecTypeId.PowerPerLength) + { + double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.PowerPerLength, propertyValue); + propertyHandle = CreateRealPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, "POWERPERLENGTH"); + } + else if (parameterType == SpecTypeId.ElectricalResistivity) + { + double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.ElectricalResistivity, propertyValue); + propertyHandle = CreateRealPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, "ELECTRICALRESISTIVITY"); + } + else if (parameterType == SpecTypeId.HeatCapacityPerArea) + { + double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.HeatCapacityPerArea, propertyValue); + propertyHandle = CreateRealPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, "HEATCAPACITYPERAREA"); + } + else if (parameterType == SpecTypeId.ThermalGradientCoefficientForMoistureCapacity) + { + double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.ThermalGradientCoefficientForMoistureCapacity, propertyValue); + propertyHandle = CreateRealPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, "THERMALGRADIENTCOEFFICIENTFORMOISTURECAPACITY"); + } + else if (parameterType == SpecTypeId.ThermalMass) + { + double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.ThermalMass, propertyValue); + propertyHandle = CreateRealPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, "THERMALMASS"); + } + else if (parameterType == SpecTypeId.AirFlowDensity) + { + double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.AirFlowDensity, propertyValue); + propertyHandle = CreateRealPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, "AIRFLOWDENSITY"); + } + else if (parameterType == SpecTypeId.AirFlowDividedByCoolingLoad) + { + double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.AirFlowDividedByCoolingLoad, propertyValue); + propertyHandle = CreateRealPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, "AIRFLOWDIVIDEDBYCOOLINGLOAD"); + } + else if (parameterType == SpecTypeId.AirFlowDividedByVolume) + { + double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.AirFlowDividedByVolume, propertyValue); + propertyHandle = CreateRealPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, "AIRFLOWDIVIDEDBYVOLUME"); + } + else if (parameterType == SpecTypeId.AreaDividedByCoolingLoad) + { + double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.AreaDividedByCoolingLoad, propertyValue); + propertyHandle = CreateRealPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, "AREADIVIDEDBYCOOLINGLOAD"); + } + else if (parameterType == SpecTypeId.AreaDividedByHeatingLoad) + { + double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.AreaDividedByHeatingLoad, propertyValue); + propertyHandle = CreateRealPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, "AREADIVIDEDBYHEATINGLOAD"); + } + else if (parameterType == SpecTypeId.CoolingLoadDividedByArea) + { + double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.CoolingLoadDividedByArea, propertyValue); + propertyHandle = CreateRealPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, "COOLINGLOADDIVIDEDBYAREA"); + } + else if (parameterType == SpecTypeId.CoolingLoadDividedByVolume) + { + double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.CoolingLoadDividedByVolume, propertyValue); + propertyHandle = CreateRealPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, "COOLINGLOADDIVIDEDBYVOLUME"); + } + else if (parameterType == SpecTypeId.FlowPerPower) + { + double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.FlowPerPower, propertyValue); + propertyHandle = CreateRealPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, "FLOWPERPOWER"); + } + else if (parameterType == SpecTypeId.HvacFriction) + { + double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.HvacFriction, propertyValue); + propertyHandle = CreateRealPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, "FRICTIONLOSS"); + } + else if (parameterType == SpecTypeId.HeatingLoadDividedByArea) + { + double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.HeatingLoadDividedByArea, propertyValue); + propertyHandle = CreateRealPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, "HEATINGLOADDIVIDEDBYAREA"); + } + else if (parameterType == SpecTypeId.HeatingLoadDividedByVolume) + { + double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.HeatingLoadDividedByVolume, propertyValue); + propertyHandle = CreateRealPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, "HEATINGLOADDIVIDEDBYVOLUME"); + } + else if (parameterType == SpecTypeId.PowerPerFlow) + { + double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.PowerPerFlow, propertyValue); + propertyHandle = CreateRealPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, "POWERPERFLOW"); + } + else if (parameterType == SpecTypeId.PipingFriction) + { + double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.PipingFriction, propertyValue); + propertyHandle = CreateRealPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, "PIPINGFRICTION"); + } + else if (parameterType == SpecTypeId.AreaSpringCoefficient) + { + double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.AreaSpringCoefficient, propertyValue); + propertyHandle = CreateRealPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, "AREASPRINGCOEFFICIENT"); + } + else if (parameterType == SpecTypeId.LineSpringCoefficient) + { + double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.LineSpringCoefficient, propertyValue); + propertyHandle = CreateRealPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, "LINESPRINGCOEFFICIENT"); + } + else if (parameterType == SpecTypeId.MassPerUnitArea) + { + double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.MassPerUnitArea, propertyValue); + propertyHandle = CreateRealPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, "MASSPERUNITAREA"); + } + else if (parameterType == SpecTypeId.ReinforcementAreaPerUnitLength) + { + double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.ReinforcementAreaPerUnitLength, propertyValue); + propertyHandle = CreateRealPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, "REINFORCEMENTAREAPERUNITLENGTH"); + } + else if (parameterType == SpecTypeId.RotationalLineSpringCoefficient) + { + double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.RotationalLineSpringCoefficient, propertyValue); + propertyHandle = CreateRealPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, "ROTATIONALLINESPRINGCOEFFICIENT"); + } + else if (parameterType == SpecTypeId.RotationalPointSpringCoefficient) + { + double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.RotationalPointSpringCoefficient, propertyValue); + propertyHandle = CreateRealPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, "ROTATIONALPOINTSPRINGCOEFFICIENT"); + } + else if (parameterType == SpecTypeId.UnitWeight) + { + double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.UnitWeight, propertyValue); + propertyHandle = CreateRealPropertyFromCache(file, propertyName, + new List() { scaledValue }, valueType, "UNITWEIGHT"); } + else + { + double scaledValue = propertyValue; + if (fallbackUnitType != null) + scaledValue = UnitUtils.ConvertFromInternalUnits(propertyValue, fallbackUnitType); - return null; - } + propertyHandle = CreateRealPropertyFromCache(file, propertyName, new List() { scaledValue }, valueType, null); + } - /// - /// Create a Diffusivity measure property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateMoistureDiffusivityPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) - { - return CreateDoublePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, - "IfcMoistureDiffusivityMeasure", SpecTypeId.Diffusivity, valueType); + return propertyHandle; } /// - /// Create a Moment Of Inertia measure property from the element's parameter. + /// Creates and associates the common property sets associated with ElementTypes. These are handled differently than for elements. /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateMomentOfInertiaPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) + /// The IFC exporter object. + /// The element type whose properties are exported. + /// The handles of property sets already associated with the type. + /// The handle of the entity associated with the element type object. + public static void CreateElementTypeProperties(ExporterIFC exporterIFC, ElementType elementType, + HashSet existingPropertySets, IFCAnyHandle prodTypeHnd) { - IFCAnyHandle propHnd = CreateMomentOfInertiaPropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; - - if (revitBuiltInParam != BuiltInParameter.INVALID) - { - string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateMomentOfInertiaPropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; - } + HashSet propertySets = new HashSet(); - return null; - } + // Pass in an empty set of handles - we don't want IfcRelDefinesByProperties for type properties. + ISet associatedObjectIds = new HashSet(); + CreateInternalRevitPropertySets(exporterIFC, elementType, associatedObjectIds, false); - /// - /// Create a Moment Of Inertia measure property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateMomentOfInertiaPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) - { - return CreateDoublePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, - "IfcMomentOfInertiaMeasure", SpecTypeId.MomentOfInertia, valueType); - } + TypePropertyInfo additionalPropertySets = null; + ElementId typeId = elementType.Id; + if (ExporterCacheManager.TypePropertyInfoCache.TryGetValue(typeId, out additionalPropertySets)) + propertySets.UnionWith(additionalPropertySets.PropertySets); - /// - /// Create a Isothermal Moisture Capacity measure property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateIsothermalMoistureCapacityPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) - { - IFCAnyHandle propHnd = CreateIsothermalMoistureCapacityPropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; + if (existingPropertySets != null && existingPropertySets.Count > 0) + propertySets.UnionWith(existingPropertySets); - if (revitBuiltInParam != BuiltInParameter.INVALID) + IFCFile file = exporterIFC.GetFile(); + using (IFCTransaction transaction = new IFCTransaction(file)) { - string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateIsothermalMoistureCapacityPropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; - } + Document doc = elementType.Document; + + IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; + + IList currPsetsToCreate = + ExporterUtil.GetCurrPSetsToCreate(prodTypeHnd, PSetsToProcess.Type); + foreach (PropertySetDescription currDesc in currPsetsToCreate) + { + // Last conditional check: if the property set comes from a ViewSchedule, check if the element is in the schedule. + if (currDesc.ViewScheduleId != ElementId.InvalidElementId) + if (!ExporterCacheManager.ViewScheduleElementCache[currDesc.ViewScheduleId].Contains(typeId)) + continue; + + ElementOrConnector elementOrConnector = new ElementOrConnector(elementType); + ISet props = currDesc.ProcessEntries(file, exporterIFC, null, elementOrConnector, elementType, prodTypeHnd); + if (props.Count > 0) + { + string paramSetName = currDesc.Name; + string guid = GUIDUtil.GenerateIFCGuidFrom( + GUIDUtil.CreateGUIDString(IFCEntityType.IfcPropertySet, paramSetName, prodTypeHnd)); + + IFCAnyHandle propertySet = IFCInstanceExporter.CreatePropertySet(file, guid, ownerHistory, paramSetName, null, props); + propertySets.Add(propertySet); + } + } + + if (propertySets.Count != 0) + { + prodTypeHnd.SetAttribute("HasPropertySets", propertySets); + // Don't assign the property sets to the instances if we have just assigned them to the type. + if (additionalPropertySets != null) + additionalPropertySets.AssignedToType = true; + } + + transaction.Commit(); + } + } + + public static IList GetDoubleValuesFromParameterByType(Element elem, string revitParameterName, ForgeTypeId specTypeId, PropertyValueType valueType) + { + List values = new List(); + + switch (valueType) + { + case PropertyValueType.SingleValue: + case PropertyValueType.ListValue: // TODO: REVIT-193510 + case PropertyValueType.TableValue: + { + double? propertyValue = GetScaledDoubleValueFromParameter(elem, revitParameterName, specTypeId); + if (propertyValue.HasValue) + values.Add(propertyValue.Value); + } + break; + case PropertyValueType.BoundedValue: + { + double? valueSetPoint = GetScaledDoubleValueFromParameter(elem, revitParameterName + ".SetPointValue", specTypeId); + double? valueUpper = GetScaledDoubleValueFromParameter(elem, revitParameterName + ".UpperBoundValue", specTypeId); + double? valueLower = GetScaledDoubleValueFromParameter(elem, revitParameterName + ".LowerBoundValue", specTypeId); + + if (valueUpper == null && valueLower == null && valueSetPoint == null) + valueUpper = GetScaledDoubleValueFromParameter(elem, revitParameterName, specTypeId); + + if (valueUpper != null || valueLower != null || valueSetPoint != null) + { + values.Add(valueSetPoint); + values.Add(valueUpper); + values.Add(valueLower); + } + } + break; + default: + throw new InvalidOperationException("Missing case!"); + + } + return values; + } + + public static double? GetScaledDoubleValueFromParameter(Element elem, string revitParameterName, ForgeTypeId specTypeId) + { + double propertyValue = 0.0; + Parameter param = ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue); + if (param != null) + { + if (!ParameterUtil.ParameterDataTypeIsEqualTo(param, SpecTypeId.Number) && + param.StorageType != StorageType.String) //The built-in parameter corresponding to "TotalWattage" is a string value in Revit that is likely going to be in the current units, and doesn't need to be scaled twice. + { + propertyValue = UnitUtil.ScaleDouble(specTypeId, propertyValue); + } + + // Convert value from internal to displayed units if we want to export it as Real + if (specTypeId == SpecTypeId.Number) + { + ForgeTypeId paramUnitType = GetParameterUnitType(param); + if (paramUnitType != null) + propertyValue = UnitUtils.ConvertFromInternalUnits(propertyValue, paramUnitType); + } + + return propertyValue; + } return null; } + #region Create___PropertyFromElement_1 /// - /// Create a Isothermal Moisture Capacity measure property from the element's parameter. + /// Create Area measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateIsothermalMoistureCapacityPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateAreaPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - return CreateDoublePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, - "IfcIsothermalMoistureCapacityMeasure", SpecTypeId.IsothermalMoistureCapacity, valueType); + IFCAnyHandle propHnd = CreateAreaPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; + + if (revitBuiltInParam != BuiltInParameter.INVALID) + { + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreateAreaPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; + } + + return null; } /// - /// Create a Isothermal Moisture Capacity measure property from the element's parameter. + /// Create Acceleration measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateIonConcentrationPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateAccelerationPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - IFCAnyHandle propHnd = CreateIonConcentrationPropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); + IFCAnyHandle propHnd = CreateAccelerationPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; if (revitBuiltInParam != BuiltInParameter.INVALID) { string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateIonConcentrationPropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); + propHnd = CreateAccelerationPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; } @@ -2954,44 +2502,54 @@ public static IList GetBoundedDataFromElement(Element elem, string revi } /// - /// Create a Ion Concentration measure property from the element's parameter. + /// Create AngularVelocity measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateIonConcentrationPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateAngularVelocityPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - return CreateDoublePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, - "IfcIonConcentrationMeasure", SpecTypeId.PipingDensity, valueType); + IFCAnyHandle propHnd = CreateAngularVelocityPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; + + if (revitBuiltInParam != BuiltInParameter.INVALID) + { + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreateAngularVelocityPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; + } + + return null; } /// - /// Create a Mass flow rate measure property from the element's parameter. + /// Create AreaDensity measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateMassFlowRatePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateAreaDensityPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - IFCAnyHandle propHnd = CreateMassFlowRatePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); + IFCAnyHandle propHnd = CreateAreaDensityPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; if (revitBuiltInParam != BuiltInParameter.INVALID) { string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateMassFlowRatePropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); + propHnd = CreateAreaDensityPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; } @@ -3000,44 +2558,54 @@ public static IList GetBoundedDataFromElement(Element elem, string revi } /// - /// Create a Mass flow rate measure property from the element's parameter. + /// Create DynamicViscosity measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateMassFlowRatePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateDynamicViscosityPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - return CreateDoublePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, - "IfcMassFlowRateMeasure", SpecTypeId.PipingMassPerTime, valueType); + IFCAnyHandle propHnd = CreateDynamicViscosityPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; + + if (revitBuiltInParam != BuiltInParameter.INVALID) + { + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreateDynamicViscosityPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; + } + + return null; } /// - /// Create a Rotational frequency measure property from the element's parameter. + /// Create ElectricCurrent measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateRotationalFrequencyPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateElectricCurrentPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - IFCAnyHandle propHnd = CreateRotationalFrequencyPropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); + IFCAnyHandle propHnd = CreateElectricCurrentPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; if (revitBuiltInParam != BuiltInParameter.INVALID) { string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateRotationalFrequencyPropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); + propHnd = CreateElectricCurrentPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; } @@ -3046,43 +2614,54 @@ public static IList GetBoundedDataFromElement(Element elem, string revi } /// - /// Create a Rotational frequency measure property from the element's parameter. + /// Create ElectricVoltage measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateRotationalFrequencyPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateElectricVoltagePropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - return CreateDoublePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, - "IfcRotationalFrequencyMeasure", SpecTypeId.AngularSpeed, valueType); + IFCAnyHandle propHnd = CreateElectricVoltagePropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; + + if (revitBuiltInParam != BuiltInParameter.INVALID) + { + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreateElectricVoltagePropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; + } + + return null; } + /// - /// Create an Area density measure property from the element's parameter. + /// Create Energy measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateAreaDensityPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateEnergyPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - IFCAnyHandle propHnd = CreateAreaDensityPropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); + IFCAnyHandle propHnd = CreateEnergyPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; if (revitBuiltInParam != BuiltInParameter.INVALID) { string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateAreaDensityPropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); + propHnd = CreateEnergyPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; } @@ -3091,44 +2670,54 @@ public static IList GetBoundedDataFromElement(Element elem, string revi } /// - /// Create an Area density measure property from the element's parameter. + /// Create Force measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateAreaDensityPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateForcePropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - return CreateDoublePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, - "IfcAreaDensityMeasure", SpecTypeId.MassPerUnitArea, valueType); + IFCAnyHandle propHnd = CreateForcePropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; + + if (revitBuiltInParam != BuiltInParameter.INVALID) + { + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreateForcePropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; + } + + return null; } /// - /// Create a Luminous flux measure property from the element's parameter. + /// Create Frequency measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateLuminousFluxMeasurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateFrequencyPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - IFCAnyHandle propHnd = CreateLuminousFluxMeasurePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); + IFCAnyHandle propHnd = CreateFrequencyPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; if (revitBuiltInParam != BuiltInParameter.INVALID) { string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateLuminousFluxMeasurePropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); + propHnd = CreateFrequencyPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; } @@ -3137,27 +2726,26 @@ public static IList GetBoundedDataFromElement(Element elem, string revi } /// - /// Create a Luminous intensity measure property from the element's parameter. + /// Create HeatingValue measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateLuminousIntensityPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateHeatingValuePropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - IFCAnyHandle propHnd = CreateLuminousIntensityMeasurePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); + IFCAnyHandle propHnd = CreateHeatingValuePropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; if (revitBuiltInParam != BuiltInParameter.INVALID) { string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateLuminousIntensityMeasurePropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); + propHnd = CreateHeatingValuePropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; } @@ -3166,27 +2754,26 @@ public static IList GetBoundedDataFromElement(Element elem, string revi } /// - /// Create a heat flux density measure property from the element's parameter. + /// Create Illuminance measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateHeatFluxDensityPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateIlluminancePropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - IFCAnyHandle propHnd = CreateHeatFluxDensityMeasurePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); + IFCAnyHandle propHnd = CreateIlluminancePropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; if (revitBuiltInParam != BuiltInParameter.INVALID) { string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateHeatFluxDensityMeasurePropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); + propHnd = CreateIlluminancePropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; } @@ -3195,27 +2782,26 @@ public static IList GetBoundedDataFromElement(Element elem, string revi } /// - /// Create an illuminance measure property from the element's parameter. + /// Create IonConcentration measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateIlluminancePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateIonConcentrationPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - IFCAnyHandle propHnd = CreateIlluminanceMeasurePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); + IFCAnyHandle propHnd = CreateIonConcentrationPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; if (revitBuiltInParam != BuiltInParameter.INVALID) { string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateIlluminanceMeasurePropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); + propHnd = CreateIonConcentrationPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; } @@ -3224,27 +2810,26 @@ public static IList GetBoundedDataFromElement(Element elem, string revi } /// - /// Create a pressure measure property from the element's parameter. + /// Create IsothermalMoistureCapacity measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreatePressurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateIsothermalMoistureCapacityPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - IFCAnyHandle propHnd = CreatePressurePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); + IFCAnyHandle propHnd = CreateIsothermalMoistureCapacityPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; if (revitBuiltInParam != BuiltInParameter.INVALID) { string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreatePressurePropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); + propHnd = CreateIsothermalMoistureCapacityPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; } @@ -3253,27 +2838,26 @@ public static IList GetBoundedDataFromElement(Element elem, string revi } /// - /// Create a ThermalConductivity measure property from the element's parameter. + /// Create HeatFluxDensity measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateThermalConductivityPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateHeatFluxDensityPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - IFCAnyHandle propHnd = CreateThermalConductivityPropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); + IFCAnyHandle propHnd = CreateHeatFluxDensityPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; if (revitBuiltInParam != BuiltInParameter.INVALID) { string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateThermalConductivityPropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); + propHnd = CreateHeatFluxDensityPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; } @@ -3282,27 +2866,26 @@ public static IList GetBoundedDataFromElement(Element elem, string revi } /// - /// Create a ThermalExpansionCoefficient measure property from the element's parameter. + /// Create Length measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateThermalExpansionCoefficientPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateLengthPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - IFCAnyHandle propHnd = CreateThermalExpansionCoefficientPropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); + IFCAnyHandle propHnd = CreateLengthPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; if (revitBuiltInParam != BuiltInParameter.INVALID) { string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateThermalExpansionCoefficientPropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); + propHnd = CreateLengthPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; } @@ -3311,27 +2894,26 @@ public static IList GetBoundedDataFromElement(Element elem, string revi } /// - /// Create a ThermalTransmittance measure property from the element's parameter. + /// Create LinearForce measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateThermalTransmittancePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateLinearForcePropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - IFCAnyHandle propHnd = CreateThermalTransmittancePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); + IFCAnyHandle propHnd = CreateLinearForcePropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; if (revitBuiltInParam != BuiltInParameter.INVALID) { string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateThermalTransmittancePropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); + propHnd = CreateLinearForcePropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; } @@ -3340,53 +2922,54 @@ public static IList GetBoundedDataFromElement(Element elem, string revi } /// - /// Create a label property from the element's parameter. + /// Create LinearMoment measure property from the element's parameter. /// /// The IFC file. /// The Element. /// The name of the parameter. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. - /// The type of the enum, null if valueType isn't EnumeratedValue. /// The created property handle. - public static IFCAnyHandle CreateLabelPropertyFromElement(IFCFile file, Element elem, string revitParameterName, string ifcPropertyName, - PropertyValueType valueType, Type propertyEnumerationType) + public static IFCAnyHandle CreateLinearMomentPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - if (elem == null) - return null; + IFCAnyHandle propHnd = CreateLinearMomentPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; - string propertyValue; - Parameter parameter = ParameterUtil.GetStringValueFromElement(elem, revitParameterName, out propertyValue); - if (parameter != null) - return CreateLabelPropertyFromCache(file, parameter.Id, ifcPropertyName, propertyValue, valueType, false, propertyEnumerationType); + if (revitBuiltInParam != BuiltInParameter.INVALID) + { + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreateLinearMomentPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; + } return null; } /// - /// Create a label property from the element's parameter. + /// Create LinearStiffness measure property from the element's parameter. /// /// The IFC file. /// The Element. /// The name of the parameter. - /// The built in parameter. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. - /// The type of the enum, null if valueType isn't EnumeratedValue. /// The created property handle. - public static IFCAnyHandle CreateLabelPropertyFromElement(IFCFile file, Element elem, string revitParameterName, - BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType, Type propertyEnumerationType) + public static IFCAnyHandle CreateLinearStiffnessPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - // For Instance - IFCAnyHandle propHnd = CreateLabelPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType, - propertyEnumerationType); + IFCAnyHandle propHnd = CreateLinearStiffnessPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; if (revitBuiltInParam != BuiltInParameter.INVALID) { string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateLabelPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType, propertyEnumerationType); + propHnd = CreateLinearStiffnessPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; } @@ -3395,48 +2978,54 @@ public static IList GetBoundedDataFromElement(Element elem, string revi } /// - /// Create an identifier property from the element's parameter. + /// Create LinearVelocity measure property from the element's parameter. /// /// The IFC file. /// The Element. /// The name of the parameter. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateIdentifierPropertyFromElement(IFCFile file, Element elem, string revitParameterName, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateLinearVelocityPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - if (elem == null) - return null; + IFCAnyHandle propHnd = CreateLinearVelocityPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; - string propertyValue; - if (ParameterUtil.GetStringValueFromElement(elem, revitParameterName, out propertyValue) != null) - return CreateIdentifierPropertyFromCache(file, ifcPropertyName, propertyValue, valueType); + if (revitBuiltInParam != BuiltInParameter.INVALID) + { + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreateLinearVelocityPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; + } return null; } /// - /// Create an identifier property from the element's parameter. + /// Create LuminousFlux measure property from the element's parameter. /// /// The IFC file. /// The Element. /// The name of the parameter. - /// The built in parameter. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateIdentifierPropertyFromElement(IFCFile file, Element elem, string revitParameterName, - BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateLuminousFluxPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - // For Instance - IFCAnyHandle propHnd = CreateIdentifierPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); + IFCAnyHandle propHnd = CreateLuminousFluxPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; if (revitBuiltInParam != BuiltInParameter.INVALID) { string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateIdentifierPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); + propHnd = CreateLuminousFluxPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; } @@ -3445,899 +3034,754 @@ public static IFCAnyHandle CreateIdentifierPropertyFromElement(IFCFile file, Ele } /// - /// Create a boolean property from the element's parameter. + /// Create LuminousIntensity measure property from the element's parameter. /// /// The IFC file. /// The Element. /// The name of the parameter. - /// The name of the property. Also, the backup name of the parameter. + /// The built in parameter to use. + /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateBooleanPropertyFromElement(IFCFile file, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateLuminousIntensityPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - int propertyValue; - if (ParameterUtil.GetIntValueFromElement(elem, revitParameterName, out propertyValue) != null) - return CreateBooleanPropertyFromCache(file, ifcPropertyName, propertyValue != 0, valueType); - if (ParameterUtil.GetIntValueFromElement(elem, ifcPropertyName, out propertyValue) != null) - return CreateBooleanPropertyFromCache(file, ifcPropertyName, propertyValue != 0, valueType); + IFCAnyHandle propHnd = CreateLuminousIntensityPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; + + if (revitBuiltInParam != BuiltInParameter.INVALID) + { + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreateLuminousIntensityPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; + } return null; } /// - /// Create a logical property from the element's or type's parameter. + /// Create Mass measure property from the element's parameter. /// /// The IFC file. /// The Element. /// The name of the parameter. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateLogicalPropertyFromElement(IFCFile file, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateMassPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - IFCLogical ifcLogical = IFCLogical.Unknown; - int propertyValue; - if (ParameterUtil.GetIntValueFromElement(elem, revitParameterName, out propertyValue) != null) - { - ifcLogical = propertyValue != 0 ? IFCLogical.True : IFCLogical.False; - } + IFCAnyHandle propHnd = CreateMassPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; - return CreateLogicalPropertyFromCache(file, ifcPropertyName, ifcLogical, valueType); + if (revitBuiltInParam != BuiltInParameter.INVALID) + { + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreateMassPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; + } + + return null; } /// - /// Create an integer property from the element's parameter. + /// Create MassDensity measure property from the element's parameter. /// /// The IFC file. /// The Element. /// The name of the parameter. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateIntegerPropertyFromElement(IFCFile file, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateMassDensityPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - int propertyValue; - if (ParameterUtil.GetIntValueFromElement(elem, revitParameterName, out propertyValue) != null) - return CreateIntegerPropertyFromCache(file, ifcPropertyName, propertyValue, valueType); + IFCAnyHandle propHnd = CreateMassDensityPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; + + if (revitBuiltInParam != BuiltInParameter.INVALID) + { + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreateMassDensityPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; + } return null; } - /// Create a real property from the element's parameter. + /// + /// Create MassFlowRate measure property from the element's parameter. + /// /// The IFC file. /// The Element. /// The name of the parameter. - /// The name of the property. Also, the backup name of the parameter. + /// The built in parameter to use. + /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateRealPropertyFromElement(IFCFile file, Element elem, string revitParameterName, string ifcPropertyName, - PropertyValueType valueType) + public static IFCAnyHandle CreateMassFlowRatePropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - double propertyValue; - Parameter param = ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue); - if (param == null) - param = ParameterUtil.GetDoubleValueFromElement(elem, ifcPropertyName, out propertyValue); + IFCAnyHandle propHnd = CreateMassFlowRatePropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; - if (param != null) + if (revitBuiltInParam != BuiltInParameter.INVALID) { - if (valueType == PropertyValueType.BoundedValue) - { - IList boundedData = GetBoundedDataFromElement(elem, revitParameterName, propertyValue, SpecTypeId.Number, "IfcReal"); - return CreateBoundedValuePropertyFromList(file, ifcPropertyName, boundedData, null); - } - else - { - ForgeTypeId paramUnitType = GetParameterUnitType(param); - if (paramUnitType != null) - propertyValue = UnitUtils.ConvertFromInternalUnits(propertyValue, paramUnitType); - - return CreateRealPropertyFromCache(file, ifcPropertyName, propertyValue, valueType); - } + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreateMassFlowRatePropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; } return null; } - /// Create a numeric property from the element's parameter. + /// + /// Create MassPerLength measure property from the element's parameter. + /// /// The IFC file. /// The Element. /// The name of the parameter. - /// The name of the property. Also, the backup name of the parameter. + /// The built in parameter to use. + /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateNumericPropertyFromElement(IFCFile file, Element elem, string revitParameterName, string ifcPropertyName, - PropertyValueType valueType) + public static IFCAnyHandle CreateMassPerLengthPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - double propertyValue; - if (ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue) != null) - { - if (valueType == PropertyValueType.BoundedValue) - { - IList boundedData = GetBoundedDataFromElement(elem, revitParameterName, propertyValue, SpecTypeId.Number, "IfcNumericMeasure"); - return CreateBoundedValuePropertyFromList(file, ifcPropertyName, boundedData, null); - } - else - { - return CreateNumericPropertyFromCache(file, ifcPropertyName, propertyValue, valueType); - } - } + IFCAnyHandle propHnd = CreateMassPerLengthPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; - if (ParameterUtil.GetDoubleValueFromElement(elem, ifcPropertyName, out propertyValue) != null) + if (revitBuiltInParam != BuiltInParameter.INVALID) { - if (valueType == PropertyValueType.BoundedValue) - { - IList boundedData = GetBoundedDataFromElement(elem, ifcPropertyName, propertyValue, SpecTypeId.Number, "IfcNumericMeasure"); - return CreateBoundedValuePropertyFromList(file, ifcPropertyName, boundedData, null); - } - else - { - return CreateNumericPropertyFromCache(file, ifcPropertyName, propertyValue, valueType); - } + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreateMassPerLengthPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; } return null; } /// - /// Create a length property from the element's or type's parameter. + /// Create ModulusOfElasticity measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. - /// The name of the built-in parameter, can be null. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateLengthMeasurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string builtInParameterName, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateModulusOfElasticityPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - double propertyValue; - - Parameter param = ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue); - if (param != null) - { - if (!ParameterUtil.ParameterDataTypeIsEqualTo(param, SpecTypeId.Number)) - propertyValue = UnitUtil.ScaleLength(propertyValue); - - if (valueType == PropertyValueType.BoundedValue) - { - IList boundedData = GetBoundedDataFromElement(elem, revitParameterName, propertyValue, SpecTypeId.Length, "IfcLengthMeasure"); - return CreateBoundedValuePropertyFromList(file, ifcPropertyName, boundedData, null); - } - else - { - return CreateLengthMeasurePropertyFromCache(file, ifcPropertyName, propertyValue, valueType); - } - } - + IFCAnyHandle propHnd = CreateModulusOfElasticityPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; - if (builtInParameterName != null) + if (revitBuiltInParam != BuiltInParameter.INVALID) { - param = ParameterUtil.GetDoubleValueFromElement(elem, builtInParameterName, out propertyValue); - if (param != null) - { - if (!ParameterUtil.ParameterDataTypeIsEqualTo(param, SpecTypeId.Number)) - propertyValue = UnitUtil.ScaleLength(propertyValue); - return CreateLengthMeasurePropertyFromCache(file, ifcPropertyName, propertyValue, valueType); - } + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreateModulusOfElasticityPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; } return null; } /// - /// Create a positive length property from the element's or type's parameter. + /// Create MoistureDiffusivity measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. - /// The name of the built-in parameter, can be null. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreatePositiveLengthMeasurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string builtInParameterName, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateMoistureDiffusivityPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - double propertyValue; - Parameter param = ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue); - if (param != null) - { - if (!ParameterUtil.ParameterDataTypeIsEqualTo(param, SpecTypeId.Number)) - propertyValue = UnitUtil.ScaleLength(propertyValue); - - if (valueType == PropertyValueType.BoundedValue) - { - IList boundedData = GetBoundedDataFromElement(elem, revitParameterName, propertyValue, SpecTypeId.Length, "IfcPositiveLengthMeasure"); - return CreateBoundedValuePropertyFromList(file, ifcPropertyName, boundedData, null); - } - else - { - return CreatePositiveLengthMeasureProperty(file, ifcPropertyName, propertyValue, valueType); - } - } + IFCAnyHandle propHnd = CreateMoistureDiffusivityPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; - if (builtInParameterName != null) + if (revitBuiltInParam != BuiltInParameter.INVALID) { - param = ParameterUtil.GetDoubleValueFromElement(elem, builtInParameterName, out propertyValue); - if (param != null) - { - if (!ParameterUtil.ParameterDataTypeIsEqualTo(param, SpecTypeId.Number)) - propertyValue = UnitUtil.ScaleLength(propertyValue); - return CreatePositiveLengthMeasureProperty(file, ifcPropertyName, propertyValue, valueType); - } + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreateMoistureDiffusivityPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; } return null; } /// - /// Create a length property from the element's parameter. + /// Create MomentOfInertia measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. - /// The optional built-in parameter. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateLengthMeasurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateMomentOfInertiaPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - string builtInParamName = null; - if (revitBuiltInParam != BuiltInParameter.INVALID) - builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - - IFCAnyHandle propHnd = CreateLengthMeasurePropertyFromElement(file, exporterIFC, elem, revitParameterName, builtInParamName, ifcPropertyName, valueType); + IFCAnyHandle propHnd = CreateMomentOfInertiaPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; + if (revitBuiltInParam != BuiltInParameter.INVALID) + { + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreateMomentOfInertiaPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; + } + return null; } /// - /// Create a positive length property from the element's parameter. + /// Create NormalisedRatio measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. - /// The optional built-in parameter. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreatePositiveLengthMeasurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateNormalisedRatioPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - string builtInParamName = null; - if (revitBuiltInParam != BuiltInParameter.INVALID) - builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - - IFCAnyHandle propHnd = CreatePositiveLengthMeasurePropertyFromElement(file, exporterIFC, elem, revitParameterName, builtInParamName, ifcPropertyName, valueType); + IFCAnyHandle propHnd = CreateNormalisedRatioPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; + if (revitBuiltInParam != BuiltInParameter.INVALID) + { + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreateNormalisedRatioPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; + } + return null; } /// - /// Create a ratio property from the element's parameter. + /// Create Numeric measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateRatioPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateNumericPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - double propertyValue; - if (ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue) != null) - return CreateRatioMeasureProperty(file, ifcPropertyName, propertyValue, valueType); - - return null; - } + IFCAnyHandle propHnd = CreateNumericPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; - /// - /// Create a ratio measure data from string value. - /// - /// The value of the property. - /// The created property data. - public static IFCData CreateRatioMeasureDataFromString(string value) - { - double propertyValue; - if (Double.TryParse(value, out propertyValue)) - return IFCDataUtil.CreateRatioMeasureData(propertyValue); + if (revitBuiltInParam != BuiltInParameter.INVALID) + { + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreateNumericPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; + } return null; } /// - /// Create a normalised ratio property from the element's parameter. + /// Create PlaneAngle measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. - /// The name of the property. Also, the backup name of the parameter. + /// The built in parameter to use. + /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateNormalisedRatioPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreatePlaneAnglePropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - double propertyValue; - if (ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue) != null) - return CreateNormalisedRatioMeasureProperty(file, ifcPropertyName, propertyValue, valueType); - if (ParameterUtil.GetDoubleValueFromElement(elem, ifcPropertyName, out propertyValue) != null) - return CreateNormalisedRatioMeasureProperty(file, ifcPropertyName, propertyValue, valueType); - - return null; - } + IFCAnyHandle propHnd = CreatePlaneAnglePropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; - /// - /// Create a normalised ratio measure data from string value. - /// - /// The value of the property. - /// The created property data. - public static IFCData CreateNormalisedRatioMeasureDataFromString(string value) - { - double propertyValue; - if (Double.TryParse(value, out propertyValue)) - return IFCDataUtil.CreateNormalisedRatioMeasureData(propertyValue); + if (revitBuiltInParam != BuiltInParameter.INVALID) + { + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreatePlaneAnglePropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; + } return null; } /// - /// Create a linear velocity property from the element's or type's parameter. + /// Create PlanarForce measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. - /// The name of the property. Also, the backup name of the parameter. + /// The built in parameter to use. + /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateLinearVelocityPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreatePlanarForcePropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { + IFCAnyHandle propHnd = CreatePlanarForcePropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; - IFCAnyHandle linearVelocityHandle = CreateDoublePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, - "IfcLinearVelocityMeasure", SpecTypeId.HvacVelocity, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(linearVelocityHandle)) - return linearVelocityHandle; + if (revitBuiltInParam != BuiltInParameter.INVALID) + { + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreatePlanarForcePropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; + } return null; } /// - /// Create a positive ratio property from the element's parameter. + /// Create PositiveLength measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. - /// The name of the property. Also, the backup name of the parameter. + /// The built in parameter to use. + /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreatePositiveRatioPropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreatePositiveLengthPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - double propertyValue; - if (ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue) != null) - return CreatePositiveRatioMeasureProperty(file, ifcPropertyName, propertyValue, valueType); - if (ParameterUtil.GetDoubleValueFromElement(elem, ifcPropertyName, out propertyValue) != null) - return CreatePositiveRatioMeasureProperty(file, ifcPropertyName, propertyValue, valueType); - - return null; - } + IFCAnyHandle propHnd = CreatePositiveLengthPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; - /// - /// Create a positive ratio measure data from string value. - /// - /// The value of the property. - /// The created property data. - public static IFCData CreatePositiveRatioMeasureDataFromString(string value) - { - double propertyValue; - if (Double.TryParse(value, out propertyValue)) - return IFCDataUtil.CreatePositiveRatioMeasureData(propertyValue); + if (revitBuiltInParam != BuiltInParameter.INVALID) + { + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreatePositiveLengthPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; + } return null; } /// - /// Create a plane angle measure property from the element's parameter. + /// Create PositiveRatio measure property from the element's parameter. /// /// The IFC file. /// The Element. /// The name of the parameter. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreatePlaneAngleMeasurePropertyFromElement(IFCFile file, Element elem, string revitParameterName, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreatePositiveRatioPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - double propertyValue; - Parameter param = ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue); - if (param != null) - { - if (!ParameterUtil.ParameterDataTypeIsEqualTo(param, SpecTypeId.Number)) - propertyValue = UnitUtil.ScaleAngle(propertyValue); + IFCAnyHandle propHnd = CreatePositiveRatioPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; - if (valueType == PropertyValueType.BoundedValue) - { - IList boundedData = GetBoundedDataFromElement(elem, revitParameterName, propertyValue, SpecTypeId.Angle, "IfcPlaneAngleMeasure"); - return CreateBoundedValuePropertyFromList(file, ifcPropertyName, boundedData, null); - } - else - { - return CreatePlaneAngleMeasurePropertyFromCache(file, ifcPropertyName, propertyValue, valueType); - } + if (revitBuiltInParam != BuiltInParameter.INVALID) + { + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreatePositiveRatioPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; } return null; } /// - /// Create an area measure property from the element's parameter. + /// Create PositivePlaneAngle measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateAreaMeasurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreatePositivePlaneAnglePropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - double propertyValue; - Parameter param = ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue); - if (param != null) - { - if (!ParameterUtil.ParameterDataTypeIsEqualTo(param, SpecTypeId.Number)) - propertyValue = UnitUtil.ScaleArea(propertyValue); + IFCAnyHandle propHnd = CreatePositivePlaneAnglePropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; - if (valueType == PropertyValueType.BoundedValue) - { - IList boundedData = GetBoundedDataFromElement(elem, revitParameterName, propertyValue, SpecTypeId.Area, "IfcAreaMeasure"); - return CreateBoundedValuePropertyFromList(file, ifcPropertyName, boundedData, null); - } - else - { - return CreateAreaMeasureProperty(file, ifcPropertyName, propertyValue, valueType); - } + if (revitBuiltInParam != BuiltInParameter.INVALID) + { + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreatePositivePlaneAnglePropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; } + return null; } /// - /// Create an Energy measure property from the element's parameter. + /// Create Power measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateEnergyMeasurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreatePowerPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - double propertyValue; - Parameter param = ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue); - if (param != null) - { - if (!ParameterUtil.ParameterDataTypeIsEqualTo(param, SpecTypeId.Number)) - propertyValue = UnitUtil.ScaleEnergy(propertyValue); - - if (valueType == PropertyValueType.BoundedValue) - { - IList boundedData = GetBoundedDataFromElement(elem, revitParameterName, propertyValue, SpecTypeId.Energy, "IfcEnergyMeasure"); - return CreateBoundedValuePropertyFromList(file, ifcPropertyName, boundedData, null); - } - else - { - return CreateEnergyMeasureProperty(file, ifcPropertyName, propertyValue, valueType); - } - } - return null; - } + IFCAnyHandle propHnd = CreatePowerPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; - /// - /// Create an ThermalResistance measure property from the element's parameter. - /// - /// The IFC file. - /// The ExporterIFC. - /// The Element. - /// The name of the parameter. - /// The name of the property. - /// The value type of the property. - /// The created property handle. - public static IFCAnyHandle CreateThermalResistanceMeasurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) - { - double propertyValue; - Parameter param = ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue); - if (param != null) + if (revitBuiltInParam != BuiltInParameter.INVALID) { - if (!ParameterUtil.ParameterDataTypeIsEqualTo(param, SpecTypeId.Number)) - propertyValue = UnitUtil.ScaleThermalResistance(propertyValue); - - if (valueType == PropertyValueType.BoundedValue) - { - IList boundedData = GetBoundedDataFromElement(elem, revitParameterName, propertyValue, SpecTypeId.ThermalResistance, "IfcThermalResistanceMeasure"); - return CreateBoundedValuePropertyFromList(file, ifcPropertyName, boundedData, null); - } - else - { - return CreateThermalResistanceMeasureProperty(file, ifcPropertyName, propertyValue, valueType); - } + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreatePowerPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; } + return null; } /// - /// Create an MassPerLength measure property from the element's parameter. + /// Create Pressure measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateMassPerLengthMeasurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreatePressurePropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - double propertyValue; - Parameter param = ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue); - if (param != null) - { - if (!ParameterUtil.ParameterDataTypeIsEqualTo(param, SpecTypeId.Number)) - propertyValue = UnitUtil.ScaleMassPerLength(propertyValue); + IFCAnyHandle propHnd = CreatePressurePropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; - if (valueType == PropertyValueType.BoundedValue) - { - IList boundedData = GetBoundedDataFromElement(elem, revitParameterName, propertyValue, SpecTypeId.MassPerUnitLength, "IfcMassPerLengthMeasure"); - return CreateBoundedValuePropertyFromList(file, ifcPropertyName, boundedData, null); - } - else - { - return CreateMassPerLengthMeasureProperty(file, ifcPropertyName, propertyValue, valueType); - } + if (revitBuiltInParam != BuiltInParameter.INVALID) + { + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreatePressurePropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; } + return null; } /// - /// Create an Acceleration measure property from the element's parameter. + /// Create Ratio measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateAccelerationMeasurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateRatioPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - double propertyValue; - Parameter param = ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue); - if (param != null) - { - if (!ParameterUtil.ParameterDataTypeIsEqualTo(param, SpecTypeId.Number)) - propertyValue = UnitUtil.ScaleAcceleration(propertyValue); + IFCAnyHandle propHnd = CreateRatioPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; - if (valueType == PropertyValueType.BoundedValue) - { - IList boundedData = GetBoundedDataFromElement(elem, revitParameterName, propertyValue, SpecTypeId.Acceleration, "IfcAccelerationMeasure"); - return CreateBoundedValuePropertyFromList(file, ifcPropertyName, boundedData, null); - } - else - { - return CreateAccelerationMeasureProperty(file, ifcPropertyName, propertyValue, valueType); - } + if (revitBuiltInParam != BuiltInParameter.INVALID) + { + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreateRatioPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; } + return null; } - /// - /// Create an LinearMoment measure property from the element's parameter. + /// Create Real measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateLinearMomentMeasurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateRealPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - double propertyValue; - Parameter param = ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue); - if (param != null) - { - if (!ParameterUtil.ParameterDataTypeIsEqualTo(param, SpecTypeId.Number)) - propertyValue = UnitUtil.ScaleLinearMoment(propertyValue); + IFCAnyHandle propHnd = CreateRealPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; - if (valueType == PropertyValueType.BoundedValue) - { - IList boundedData = GetBoundedDataFromElement(elem, revitParameterName, propertyValue, SpecTypeId.LinearMoment, "IfcLinearMomentMeasure"); - return CreateBoundedValuePropertyFromList(file, ifcPropertyName, boundedData, null); - } - else - { - return CreateLinearMomentMeasureProperty(file, ifcPropertyName, propertyValue, valueType); - } + if (revitBuiltInParam != BuiltInParameter.INVALID) + { + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreateRealPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; } + return null; } /// - /// Create an Torque measure property from the element's parameter. + /// Create RotationalFrequency measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateTorqueMeasurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateRotationalFrequencyPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - double propertyValue; - Parameter param = ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue); - if (param != null) - { - if (!ParameterUtil.ParameterDataTypeIsEqualTo(param, SpecTypeId.Number)) - propertyValue = UnitUtil.ScaleTorque(propertyValue); + IFCAnyHandle propHnd = CreateRotationalFrequencyPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; - if (valueType == PropertyValueType.BoundedValue) - { - IList boundedData = GetBoundedDataFromElement(elem, revitParameterName, propertyValue, SpecTypeId.Moment, "IfcTorqueMeasure"); - return CreateBoundedValuePropertyFromList(file, ifcPropertyName, boundedData, null); - } - else - { - return CreateTorqueMeasureProperty(file, ifcPropertyName, propertyValue, valueType); - } + if (revitBuiltInParam != BuiltInParameter.INVALID) + { + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreateRotationalFrequencyPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; } + return null; } /// - /// Create an LinearStiffness measure property from the element's parameter. + /// Create SoundPower measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateLinearStiffnessMeasurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateSoundPowerPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - double propertyValue; - Parameter param = ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue); - if (param != null) - { - if (!ParameterUtil.ParameterDataTypeIsEqualTo(param, SpecTypeId.Number)) - propertyValue = UnitUtil.ScaleLinearStiffness(propertyValue); + IFCAnyHandle propHnd = CreateSoundPowerPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; - if (valueType == PropertyValueType.BoundedValue) - { - IList boundedData = GetBoundedDataFromElement(elem, revitParameterName, propertyValue, SpecTypeId.PointSpringCoefficient, "IfcLinearStiffnessMeasure"); - return CreateBoundedValuePropertyFromList(file, ifcPropertyName, boundedData, null); - } - else - { - return CreateLinearStiffnessMeasureProperty(file, ifcPropertyName, propertyValue, valueType); - } + if (revitBuiltInParam != BuiltInParameter.INVALID) + { + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreateSoundPowerPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; } + return null; } /// - /// Create an AngularVelocity measure property from the element's parameter. + /// Create SoundPressure measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateAngularVelocityMeasurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateSoundPressurePropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - double propertyValue; - Parameter param = ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue); - if (param != null) - { - if (!ParameterUtil.ParameterDataTypeIsEqualTo(param, SpecTypeId.Number)) - propertyValue = UnitUtil.ScaleAngularVelocity(propertyValue); + IFCAnyHandle propHnd = CreateSoundPressurePropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; - if (valueType == PropertyValueType.BoundedValue) - { - IList boundedData = GetBoundedDataFromElement(elem, revitParameterName, propertyValue, SpecTypeId.Pulsation, "IfcAngularVelocityMeasure"); - return CreateBoundedValuePropertyFromList(file, ifcPropertyName, boundedData, null); - } - else - { - return CreateAngularVelocityMeasureProperty(file, ifcPropertyName, propertyValue, valueType); - } + if (revitBuiltInParam != BuiltInParameter.INVALID) + { + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreateSoundPressurePropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; } + return null; } /// - /// Create an WarpingConstant measure property from the element's parameter. + /// Create SpecificHeatCapacity measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateWarpingConstantMeasurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateSpecificHeatCapacityPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - double propertyValue; - Parameter param = ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue); - if (param != null) - { - if (!ParameterUtil.ParameterDataTypeIsEqualTo(param, SpecTypeId.Number)) - propertyValue = UnitUtil.ScaleWarpingConstant(propertyValue); + IFCAnyHandle propHnd = CreateSpecificHeatCapacityPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; - if (valueType == PropertyValueType.BoundedValue) - { - IList boundedData = GetBoundedDataFromElement(elem, revitParameterName, propertyValue, SpecTypeId.WarpingConstant, "IfcWarpingConstantMeasure"); - return CreateBoundedValuePropertyFromList(file, ifcPropertyName, boundedData, null); - } - else - { - return CreateWarpingConstantMeasureProperty(file, ifcPropertyName, propertyValue, valueType); - } + if (revitBuiltInParam != BuiltInParameter.INVALID) + { + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreateSpecificHeatCapacityPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; } + return null; } /// - /// Create an vapor permeability measure property from the element's parameter. + /// Create ThermalConductivity measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateVaporPermeabilityMeasurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateThermalConductivityPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - double propertyValue; - Parameter param = ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue); - if (param != null) - { - if (!ParameterUtil.ParameterDataTypeIsEqualTo(param, SpecTypeId.Number)) - propertyValue = UnitUtil.ScaleVaporPermeability(propertyValue); + IFCAnyHandle propHnd = CreateThermalConductivityPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; - if (valueType == PropertyValueType.BoundedValue) - { - IList boundedData = GetBoundedDataFromElement(elem, revitParameterName, propertyValue, SpecTypeId.Permeability, "IfcVaporPermeabilityMeasure"); - return CreateBoundedValuePropertyFromList(file, ifcPropertyName, boundedData, null); - } - else - { - return CreateVaporPermeabilityMeasureProperty(file, ifcPropertyName, propertyValue, valueType); - } + if (revitBuiltInParam != BuiltInParameter.INVALID) + { + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreateThermalConductivityPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; } + return null; } /// - /// Create an volume measure property from the element's parameter. + /// Create ThermalExpansionCoefficient measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateVolumeMeasurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateThermalExpansionCoefficientPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - double propertyValue; - Parameter param = ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValue); - if (param != null) - { - if (!ParameterUtil.ParameterDataTypeIsEqualTo(param, SpecTypeId.Number)) - propertyValue = UnitUtil.ScaleVolume(propertyValue); + IFCAnyHandle propHnd = CreateThermalExpansionCoefficientPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; - if (valueType == PropertyValueType.BoundedValue) - { - IList boundedData = GetBoundedDataFromElement(elem, revitParameterName, propertyValue, SpecTypeId.Volume, "IfcVolumeMeasure"); - return CreateBoundedValuePropertyFromList(file, ifcPropertyName, boundedData, null); - } - else - { - return CreateVolumeMeasureProperty(file, ifcPropertyName, propertyValue, valueType); - } + if (revitBuiltInParam != BuiltInParameter.INVALID) + { + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreateThermalExpansionCoefficientPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; } + return null; } /// - /// Create a count measure property from the element's parameter. + /// Create ThermalResistance measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateCountMeasurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateThermalResistancePropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - int propertyValue; - double propertyValueReal; - if (ParameterUtil.GetDoubleValueFromElement(elem, revitParameterName, out propertyValueReal) != null) + IFCAnyHandle propHnd = CreateThermalResistancePropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; + + if (revitBuiltInParam != BuiltInParameter.INVALID) { - if (ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4x3) - { - return CreateCountMeasureProperty(file, ifcPropertyName, propertyValueReal, valueType); - } - else if (MathUtil.IsAlmostInteger(propertyValueReal)) - { - propertyValue = (int)Math.Floor(propertyValueReal); - return CreateCountMeasureProperty(file, ifcPropertyName, propertyValue, valueType); - } + string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); + propHnd = CreateThermalResistancePropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) + return propHnd; } - if (ParameterUtil.GetIntValueFromElement(elem, revitParameterName, out propertyValue) != null) - return CreateCountMeasureProperty(file, ifcPropertyName, propertyValue, valueType); - return null; } /// - /// Create an area measure property from the element's parameter. + /// Create ThermalTransmittance measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateAreaMeasurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateThermalTransmittancePropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - IFCAnyHandle propHnd = CreateAreaMeasurePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); + IFCAnyHandle propHnd = CreateThermalTransmittancePropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; if (revitBuiltInParam != BuiltInParameter.INVALID) { string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateAreaMeasurePropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); + propHnd = CreateThermalTransmittancePropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; } @@ -4346,27 +3790,26 @@ public static IFCAnyHandle CreatePlaneAngleMeasurePropertyFromElement(IFCFile fi } /// - /// Create an Energy measure property from the element's parameter. + /// Create ThermodynamicTemperature measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateEnergyMeasurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateThermodynamicTemperaturePropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - IFCAnyHandle propHnd = CreateEnergyMeasurePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); + IFCAnyHandle propHnd = CreateThermodynamicTemperaturePropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; if (revitBuiltInParam != BuiltInParameter.INVALID) { string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateEnergyMeasurePropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); + propHnd = CreateThermodynamicTemperaturePropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; } @@ -4375,27 +3818,26 @@ public static IFCAnyHandle CreatePlaneAngleMeasurePropertyFromElement(IFCFile fi } /// - /// Create an ThermalResistance measure property from the element's parameter. + /// Create VaporPermeability measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateThermalResistanceMeasurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateVaporPermeabilityPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - IFCAnyHandle propHnd = CreateThermalResistanceMeasurePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); + IFCAnyHandle propHnd = CreateVaporPermeabilityPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; if (revitBuiltInParam != BuiltInParameter.INVALID) { string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateThermalResistanceMeasurePropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); + propHnd = CreateVaporPermeabilityPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; } @@ -4404,27 +3846,26 @@ public static IFCAnyHandle CreatePlaneAngleMeasurePropertyFromElement(IFCFile fi } /// - /// Create an MassPerLength measure property from the element's parameter. + /// Create Volume measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateMassPerLengthMeasurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateVolumePropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - IFCAnyHandle propHnd = CreateMassPerLengthMeasurePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); + IFCAnyHandle propHnd = CreateVolumePropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; if (revitBuiltInParam != BuiltInParameter.INVALID) { string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateMassPerLengthMeasurePropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); + propHnd = CreateVolumePropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; } @@ -4433,27 +3874,26 @@ public static IFCAnyHandle CreatePlaneAngleMeasurePropertyFromElement(IFCFile fi } /// - /// Create an Acceleration measure property from the element's parameter. + /// Create VolumetricFlowRate measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateAccelerationMeasurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateVolumetricFlowRatePropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - IFCAnyHandle propHnd = CreateAccelerationMeasurePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); + IFCAnyHandle propHnd = CreateVolumetricFlowRatePropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; if (revitBuiltInParam != BuiltInParameter.INVALID) { string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateAccelerationMeasurePropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); + propHnd = CreateVolumetricFlowRatePropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; } @@ -4462,27 +3902,26 @@ public static IFCAnyHandle CreatePlaneAngleMeasurePropertyFromElement(IFCFile fi } /// - /// Create an LinearMoment measure property from the element's parameter. + /// Create Torque measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateLinearMomentMeasurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateTorquePropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - IFCAnyHandle propHnd = CreateLinearMomentMeasurePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); + IFCAnyHandle propHnd = CreateTorquePropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; if (revitBuiltInParam != BuiltInParameter.INVALID) { string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateLinearMomentMeasurePropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); + propHnd = CreateTorquePropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; } @@ -4491,1285 +3930,2706 @@ public static IFCAnyHandle CreatePlaneAngleMeasurePropertyFromElement(IFCFile fi } /// - /// Create an Torque measure property from the element's parameter. + /// Create WarpingConstant measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. + /// The built in parameter to use. /// The name of the property. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateTorqueMeasurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateWarpingConstantPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) { - IFCAnyHandle propHnd = CreateTorqueMeasurePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); + IFCAnyHandle propHnd = CreateWarpingConstantPropertyFromElement(file, elem, revitParameterName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; if (revitBuiltInParam != BuiltInParameter.INVALID) { string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateTorqueMeasurePropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); + propHnd = CreateWarpingConstantPropertyFromElement(file, elem, builtInParamName, ifcPropertyName, valueType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) return propHnd; } return null; } + #endregion + + #region Create___PropertyFromElement_2 /// - /// Create an LinearStiffness measure property from the element's parameter. + /// Create a Area measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. - /// The name of the property. + /// The name of the property. Also, the backup name of the parameter. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateLinearStiffnessMeasurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateAreaPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) { - IFCAnyHandle propHnd = CreateLinearStiffnessMeasurePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.Area, valueType); + IFCAnyHandle property = CreateAreaPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); - if (revitBuiltInParam != BuiltInParameter.INVALID) + if (property == null) { - string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateLinearStiffnessMeasurePropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.Area, valueType); + property = CreateAreaPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - return null; + return property; } /// - /// Create an AngularVelocity measure property from the element's parameter. + /// Create a Acceleration measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. - /// The name of the property. + /// The name of the property. Also, the backup name of the parameter. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateAngularVelocityMeasurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateAccelerationPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) { - IFCAnyHandle propHnd = CreateAngularVelocityMeasurePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.Acceleration, valueType); + IFCAnyHandle property = CreateAccelerationPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); - if (revitBuiltInParam != BuiltInParameter.INVALID) + if (property == null) { - string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateAngularVelocityMeasurePropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.Acceleration, valueType); + property = CreateAccelerationPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - return null; + return property; } /// - /// Create an WarpingConstant measure property from the element's parameter. + /// Create a AngularVelocity measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. - /// The name of the property. + /// The name of the property. Also, the backup name of the parameter. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateWarpingConstantMeasurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateAngularVelocityPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) { - IFCAnyHandle propHnd = CreateWarpingConstantMeasurePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.Pulsation, valueType); + IFCAnyHandle property = CreateAngularVelocityPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); - if (revitBuiltInParam != BuiltInParameter.INVALID) + if (property == null) { - string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateWarpingConstantMeasurePropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.Pulsation, valueType); + property = CreateAngularVelocityPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - return null; + return property; } /// - /// Create an vapor permeability measure property from the element's parameter. + /// Create a AreaDensity measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. - /// The name of the property. + /// The name of the property. Also, the backup name of the parameter. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateVaporPermeabilityMeasurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateAreaDensityPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) { - IFCAnyHandle propHnd = CreateVaporPermeabilityMeasurePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.MassPerUnitArea, valueType); + IFCAnyHandle property = CreateAreaDensityPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); - if (revitBuiltInParam != BuiltInParameter.INVALID) + if (property == null) { - string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateVaporPermeabilityMeasurePropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.MassPerUnitArea, valueType); + property = CreateAreaDensityPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - return null; + return property; } /// - /// Create an volume measure property from the element's parameter. + /// Create a DynamicViscosity measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. - /// The name of the property. + /// The name of the property. Also, the backup name of the parameter. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateVolumeMeasurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateDynamicViscosityPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) { - IFCAnyHandle propHnd = CreateVolumeMeasurePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.HvacViscosity, valueType); + IFCAnyHandle property = CreateDynamicViscosityPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); - if (revitBuiltInParam != BuiltInParameter.INVALID) + if (property == null) { - string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateVolumeMeasurePropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.HvacViscosity, valueType); + property = CreateDynamicViscosityPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - return null; + return property; } /// - /// Create a count measure property from the element's parameter. + /// Create a ElectricCurrent measure property from the element's parameter. /// /// The IFC file. - /// The ExporterIFC. /// The Element. /// The name of the parameter. - /// The built in parameter to use, if revitParameterName isn't found. - /// The name of the property. + /// The name of the property. Also, the backup name of the parameter. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateCountMeasurePropertyFromElement(IFCFile file, ExporterIFC exporterIFC, Element elem, - string revitParameterName, BuiltInParameter revitBuiltInParam, string ifcPropertyName, PropertyValueType valueType) + public static IFCAnyHandle CreateElectricCurrentPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) { - IFCAnyHandle propHnd = CreateCountMeasurePropertyFromElement(file, exporterIFC, elem, revitParameterName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.Current, valueType); + IFCAnyHandle property = CreateElectricCurrentPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); - if (revitBuiltInParam != BuiltInParameter.INVALID) + if (property == null) { - string builtInParamName = LabelUtils.GetLabelFor(revitBuiltInParam); - propHnd = CreateCountMeasurePropertyFromElement(file, exporterIFC, elem, builtInParamName, ifcPropertyName, valueType); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propHnd)) - return propHnd; + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.Current, valueType); + property = CreateElectricCurrentPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - return null; + return property; } /// - /// Creates the shared beam and column QTO values. + /// Create a ElectricVoltage measure property from the element's parameter. /// - /// - /// This code uses the native implementation for creating these quantities, and the native class for storing the information. - /// This will be obsoleted. - /// - /// The exporter. - /// The element handle. - /// The beam or column element. - /// The FamilyTypeInfo containing the appropriate data. - /// The list of geometries for the exported column only, used if split walls and columns is set. - /// The geomObjects is used if we have the split by level option. It is intended only for columns, as beams and members are not split by level. - /// In this case, we use the solids in the list to determine the real volume of the exported objects. If the list contains meshes, we won't export the volume at all. - public static void CreateBeamColumnBaseQuantities(ExporterIFC exporterIFC, IFCAnyHandle elemHandle, Element element, FamilyTypeInfo typeInfo, IList geomObjects) + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateElectricVoltagePropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) { - // Make sure QTO export is enabled. - if (!ExporterCacheManager.ExportOptionsCache.ExportBaseQuantities || (ExporterCacheManager.ExportOptionsCache.ExportAsCOBIE)) - return; - - IFCFile file = exporterIFC.GetFile(); - HashSet quantityHnds = new HashSet(); - double scaledLength = typeInfo.extraParams.ScaledLength; - //According to investigation of current code the passed in typeInfo contains grossArea - double scaledGrossArea = typeInfo.extraParams.ScaledArea; - double crossSectionArea = scaledGrossArea; - double scaledOuterPerimeter = typeInfo.extraParams.ScaledOuterPerimeter; - double scaledInnerPerimeter = typeInfo.extraParams.ScaledInnerPerimeter; - double outSurfaceArea = 0.0; + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.ElectricalPotential, valueType); + IFCAnyHandle property = CreateElectricVoltagePropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); - if (scaledLength > MathUtil.Eps()) + if (property == null) { - IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityLength(file, "Length", null, null, scaledLength); - quantityHnds.Add(quantityHnd); + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.ElectricalPotential, valueType); + property = CreateElectricVoltagePropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - if (MathUtil.AreaIsAlmostZero(crossSectionArea)) - { - if (element != null) - { - ParameterUtil.GetDoubleValueFromElement(element, BuiltInParameter.HOST_AREA_COMPUTED, out crossSectionArea); - crossSectionArea = UnitUtil.ScaleArea(crossSectionArea); - } - } + return property; + } - if (!MathUtil.AreaIsAlmostZero(crossSectionArea)) + /// + /// Create a Energy measure property from the element's parameter. + /// + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateEnergyPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) + { + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.Energy, valueType); + IFCAnyHandle property = CreateEnergyPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); + + if (property == null) { - IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityArea(file, "CrossSectionArea", null, null, crossSectionArea); - quantityHnds.Add(quantityHnd); + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.Energy, valueType); + property = CreateEnergyPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - if (!MathUtil.AreaIsAlmostZero(scaledGrossArea) && !MathUtil.IsAlmostZero(scaledLength) && !MathUtil.IsAlmostZero(scaledOuterPerimeter)) + return property; + } + + /// + /// Create a Force measure property from the element's parameter. + /// + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateForcePropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) + { + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.Force, valueType); + IFCAnyHandle property = CreateForcePropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); + + if (property == null) { - double scaledPerimeter = scaledOuterPerimeter + scaledInnerPerimeter; - //According to the IFC documentation, OuterSurfaceArea does not include the end caps area, only Length * Perimeter - outSurfaceArea = UnitUtil.ScaleArea(UnitUtil.UnscaleLength(scaledLength) * UnitUtil.UnscaleLength(scaledPerimeter)); - IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityArea(file, "OuterSurfaceArea", null, null, outSurfaceArea); - quantityHnds.Add(quantityHnd); + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.Force, valueType); + property = CreateForcePropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - // Compute GrossSurfaceArea if both CrossSectionAre and OuterSurfaceArea cannot be determined separately - if (MathUtil.AreaIsAlmostZero(crossSectionArea) && MathUtil.AreaIsAlmostZero(outSurfaceArea)) + return property; + } + + /// + /// Create a Frequency measure property from the element's parameter. + /// + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateFrequencyPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) + { + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.Number, valueType); + IFCAnyHandle property = CreateFrequencyPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); + + if (property == null) { - double scaledPerimeter = scaledOuterPerimeter + scaledInnerPerimeter; - double grossSurfaceArea = scaledGrossArea * 2 + UnitUtil.ScaleArea(UnitUtil.UnscaleLength(scaledLength) * UnitUtil.UnscaleLength(scaledPerimeter)); - IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityArea(file, "GrossSurfaceArea", null, null, grossSurfaceArea); - quantityHnds.Add(quantityHnd); + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.Number, valueType); + property = CreateFrequencyPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - double grossVolume = UnitUtil.ScaleVolume(UnitUtil.UnscaleLength(scaledLength) * UnitUtil.UnscaleArea(scaledGrossArea)); - double netVolume = 0.0; - if (element != null) - { - // If we are splitting columns, we will look at the actual geometry used when exporting this segment - // of the column, but only if we have the geomObjects passed in. - if (geomObjects != null && ExporterCacheManager.ExportOptionsCache.WallAndColumnSplitting) - { - foreach (GeometryObject geomObj in geomObjects) - { - // We don't suport calculating the volume of Meshes at this time. - if (geomObj is Mesh) - { - netVolume = 0.0; - break; - } + return property; + } - if (geomObj is Solid) - netVolume += (geomObj as Solid).Volume; - } - } - else - ParameterUtil.GetDoubleValueFromElement(element, BuiltInParameter.HOST_VOLUME_COMPUTED, out netVolume); - netVolume = UnitUtil.ScaleVolume(netVolume); - } + /// + /// Create a HeatingValue measure property from the element's parameter. + /// + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateHeatingValuePropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) + { + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.SpecificHeatOfVaporization, valueType); + IFCAnyHandle property = CreateHeatingValuePropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); - if (!MathUtil.VolumeIsAlmostZero(grossVolume)) + if (property == null) { - IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityVolume(file, "GrossVolume", null, null, grossVolume); - quantityHnds.Add(quantityHnd); + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.SpecificHeatOfVaporization, valueType); + property = CreateHeatingValuePropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - if (!MathUtil.VolumeIsAlmostZero(netVolume)) + return property; + } + + /// + /// Create a Illuminance measure property from the element's parameter. + /// + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateIlluminancePropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) + { + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.Illuminance, valueType); + IFCAnyHandle property = CreateIlluminancePropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); + + if (property == null) { - IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityVolume(file, "NetVolume", null, null, netVolume); - quantityHnds.Add(quantityHnd); + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.Illuminance, valueType); + property = CreateIlluminancePropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - string quantitySetName = string.Empty; - if (!ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4) + return property; + } + + /// + /// Create a IonConcentration measure property from the element's parameter. + /// + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateIonConcentrationPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) + { + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.PipingDensity, valueType); + IFCAnyHandle property = CreateIonConcentrationPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); + + if (property == null) { - if (IFCAnyHandleUtil.IsSubTypeOf(elemHandle, Common.Enums.IFCEntityType.IfcColumn)) - quantitySetName = "Qto_ColumnBaseQuantities"; - if (IFCAnyHandleUtil.IsSubTypeOf(elemHandle, Common.Enums.IFCEntityType.IfcBeam)) - quantitySetName = "Qto_BeamBaseQuantities"; - if (IFCAnyHandleUtil.IsSubTypeOf(elemHandle, Common.Enums.IFCEntityType.IfcMember)) - quantitySetName = "Qto_MemberBaseQuantities"; + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.PipingDensity, valueType); + property = CreateIonConcentrationPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - CreateAndRelateBaseQuantities(file, exporterIFC, elemHandle, quantityHnds, quantitySetName); + + return property; } /// - /// Creates the spatial element quantities required by GSA before COBIE and adds them to the export. + /// Create a IsothermalMoistureCapacity measure property from the element's parameter. /// - /// The exporter. - /// The element handle. - /// The quantity name. - /// The area name. - /// The area. - public static void CreatePreCOBIEGSAQuantities(ExporterIFC exporterIFC, IFCAnyHandle elemHnd, string quantityName, string areaName, double area) + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateIsothermalMoistureCapacityPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) { - IFCFile file = exporterIFC.GetFile(); - IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; - IFCAnyHandle areaQuantityHnd = IFCInstanceExporter.CreateQuantityArea(file, quantityName, null, null, area); - HashSet areaQuantityHnds = new HashSet(); - areaQuantityHnds.Add(areaQuantityHnd); + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.IsothermalMoistureCapacity, valueType); + IFCAnyHandle property = CreateIsothermalMoistureCapacityPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); - PropertyUtil.CreateAndRelateBaseQuantities(file, exporterIFC, elemHnd, areaQuantityHnds, quantityName, null, areaName); + if (property == null) + { + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.IsothermalMoistureCapacity, valueType); + property = CreateIsothermalMoistureCapacityPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); + } + + return property; } /// - /// Creates the opening quantities and adds them to the export. + /// Create a HeatFluxDensity measure property from the element's parameter. /// - /// The exporter. - /// The opening element handle. - /// The extrusion creation data. - public static void CreateOpeningQuantities(ExporterIFC exporterIFC, IFCAnyHandle openingElement, IFCExportBodyParams extraParams) + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateHeatFluxDensityPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) { - IFCFile file = exporterIFC.GetFile(); - HashSet quantityHnds = new HashSet(); - if (extraParams.ScaledLength > MathUtil.Eps()) - { - IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityLength(file, "Depth", null, null, extraParams.ScaledLength); - quantityHnds.Add(quantityHnd); - } - if (extraParams.ScaledHeight > MathUtil.Eps()) - { - IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityLength(file, "Height", null, null, extraParams.ScaledHeight); - quantityHnds.Add(quantityHnd); - quantityHnd = IFCInstanceExporter.CreateQuantityLength(file, "Width", null, null, extraParams.ScaledWidth); - quantityHnds.Add(quantityHnd); - } - else if (extraParams.ScaledArea > MathUtil.Eps()) - { - IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityArea(file, "Area", null, null, extraParams.ScaledArea); - quantityHnds.Add(quantityHnd); - } + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.HvacPowerDensity, valueType); + IFCAnyHandle property = CreateHeatFluxDensityPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); - string quantitySetName = string.Empty; - if (!ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4) + if (property == null) { - quantitySetName = "Qto_OpeningElementBaseQuantities"; + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.HvacPowerDensity, valueType); + property = CreateHeatFluxDensityPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - CreateAndRelateBaseQuantities(file, exporterIFC, openingElement, quantityHnds, quantitySetName); + + return property; } /// - /// Creates the wall base quantities and adds them to the export. + /// Create a Length measure property from the element's parameter. /// - /// The exporter. - /// The wall element. - /// The wall handle. - /// The list of solids for the entity created for the wall element. - /// The list of meshes for the entity created for the wall element. - /// The scaled length. - /// The scaled depth. - /// The scaled foot print area. - /// If we are splitting walls by level, the list of solids and meshes represent the currently - /// exported section of wall, not the entire wall. - public static void CreateWallBaseQuantities(ExporterIFC exporterIFC, Wall wallElement, - IList solids, IList meshes, - IFCAnyHandle wallHnd, - double scaledLength, double scaledDepth, double scaledFootPrintArea, - IFCExportBodyParams extrustionData, HashSet widthAsComplexQty = null) + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateLengthPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) { - IFCFile file = exporterIFC.GetFile(); - HashSet quantityHnds = new HashSet(); - if (scaledDepth > MathUtil.Eps()) - { - IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityLength(file, "Height", null, null, scaledDepth); - quantityHnds.Add(quantityHnd); - } + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.Length, valueType); + IFCAnyHandle property = CreateLengthPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); - if (!MathUtil.IsAlmostZero(scaledLength)) - { - IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityLength(file, "Length", null, null, scaledLength); - quantityHnds.Add(quantityHnd); - } - else if (wallElement.Location != null) + if (property == null) { - Curve wallAxis = (wallElement.Location as LocationCurve).Curve; - if (wallAxis != null) - { - double axisLength = UnitUtil.ScaleLength(wallAxis.Length); - IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityLength(file, "Length", null, null, axisLength); - quantityHnds.Add(quantityHnd); - } + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.Length, valueType); + property = CreateLengthPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } + return property; + } - double scaledWidth = 0.0; - if (wallElement != null) - { - scaledWidth = UnitUtil.ScaleLength(wallElement.Width); - if (!MathUtil.IsAlmostZero(scaledWidth)) - { - if ((widthAsComplexQty?.Count ?? 0) == 0) - { - IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityLength(file, "Width", null, null, scaledWidth); - quantityHnds.Add(quantityHnd); - } - else - { - quantityHnds.UnionWith(widthAsComplexQty); - } - } - } + /// + /// Create a LinearForce measure property from the element's parameter. + /// + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateLinearForcePropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) + { + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.LinearForce, valueType); + IFCAnyHandle property = CreateLinearForcePropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); - if (!MathUtil.IsAlmostZero(scaledFootPrintArea)) + if (property == null) { - IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityArea(file, "GrossFootprintArea", null, null, scaledFootPrintArea); - quantityHnds.Add(quantityHnd); + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.LinearForce, valueType); + property = CreateLinearForcePropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - double netArea = 0; - double grossArea = 0; - double volume = 0; + return property; + } - // We will only assign the area if we have all solids that we are exporting; we won't bother calcuting values for Meshes. - if (solids != null && (meshes == null || meshes.Count == 0)) - { - foreach (Solid solid in solids) - { - double largestFaceNetArea = 0.0; - double largestFaceGrossArea = 0.0; - foreach (Face face in solid.Faces) - { - XYZ fNormal = face.ComputeNormal(new UV(0, 0)); - if (MathUtil.IsAlmostZero(fNormal.Z)) - { - if (face.Area > largestFaceNetArea) - largestFaceNetArea = face.Area; // collecting largest face on the XY plane. It will be used for NetArea + /// + /// Create a LinearMoment measure property from the element's parameter. + /// + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateLinearMomentPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) + { + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.LinearMoment, valueType); + IFCAnyHandle property = CreateLinearMomentPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); - IList fCurveLoops = face.GetEdgesAsCurveLoops(); - double grArea = ExporterIFCUtils.ComputeAreaOfCurveLoops(new List() { fCurveLoops[0] }); - if (grArea > largestFaceGrossArea) - largestFaceGrossArea = grArea; - } - } - netArea += largestFaceNetArea; - grossArea += largestFaceGrossArea; - volume += solid.Volume; - } + if (property == null) + { + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.LinearMoment, valueType); + property = CreateLinearMomentPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - netArea = UnitUtil.ScaleArea(netArea); - grossArea = UnitUtil.ScaleArea(grossArea); - volume = UnitUtil.ScaleVolume(volume); + return property; + } - if (scaledDepth > MathUtil.Eps() && !MathUtil.IsAlmostZero(scaledWidth) && !MathUtil.IsAlmostZero(grossArea)) - { - double grossVolume = UnitUtil.ScaleVolume(UnitUtil.UnscaleLength(scaledWidth) * UnitUtil.UnscaleArea(grossArea)); - IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityVolume(file, "GrossVolume", null, null, grossVolume); - quantityHnds.Add(quantityHnd); - } + /// + /// Create a LinearStiffness measure property from the element's parameter. + /// + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateLinearStiffnessPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) + { + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.PointSpringCoefficient, valueType); + IFCAnyHandle property = CreateLinearStiffnessPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); - if (!MathUtil.IsAlmostZero(grossArea)) + if (property == null) { - IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityArea(file, "GrossSideArea", null, null, grossArea); - quantityHnds.Add(quantityHnd); + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.PointSpringCoefficient, valueType); + property = CreateLinearStiffnessPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - if (!MathUtil.IsAlmostZero(netArea)) - { - IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityArea(file, "NetSideArea", null, null, netArea); - quantityHnds.Add(quantityHnd); - } + return property; + } - if (!MathUtil.IsAlmostZero(volume)) - { - IFCAnyHandle quantityHnd = IFCInstanceExporter.CreateQuantityVolume(file, "NetVolume", null, null, volume); - quantityHnds.Add(quantityHnd); - } + /// + /// Create a LinearVelocity measure property from the element's parameter. + /// + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateLinearVelocityPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) + { + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.HvacVelocity, valueType); + IFCAnyHandle property = CreateLinearVelocityPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); - string quantitySetName = string.Empty; - if (ExporterCacheManager.ExportOptionsCache.ExportAs4) + if (property == null) { - quantitySetName = "Qto_WallBaseQuantities"; + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.HvacVelocity, valueType); + property = CreateLinearVelocityPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - CreateAndRelateBaseQuantities(file, exporterIFC, wallHnd, quantityHnds, quantitySetName); + return property; } /// - /// Creates and relate base quantities to quantity handle. + /// Create a LuminousFlux measure property from the element's parameter. /// - /// The file. - /// The exporter. - /// The element handle. - /// The quantity handles. - static public void CreateAndRelateBaseQuantities(IFCFile file, ExporterIFC exporterIFC, IFCAnyHandle elemHnd, HashSet quantityHnds, - string quantitySetName = null, string description = null, string methodOfMeasurement = null) + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateLuminousFluxPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) { - if (quantityHnds.Count > 0) - { - if (string.IsNullOrEmpty(quantitySetName)) - quantitySetName = "BaseQuantities"; - IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; - - // Skip if the elementHandle has the associated QuantitySet has been created before - if (!ExporterCacheManager.QtoSetCreated.Contains((elemHnd, quantitySetName))) - { - string quantityGuid = GUIDUtil.GenerateIFCGuidFrom( - GUIDUtil.CreateGUIDString(IFCEntityType.IfcElementQuantity, quantitySetName, elemHnd)); - IFCAnyHandle quantity = IFCInstanceExporter.CreateElementQuantity(file, elemHnd, - quantityGuid, ownerHistory, quantitySetName, description, - methodOfMeasurement, quantityHnds); - HashSet relatedObjects = new HashSet(); - relatedObjects.Add(elemHnd); + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.LuminousFlux, valueType); + IFCAnyHandle property = CreateLuminousFluxPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); - string quantityRelGuid = GUIDUtil.GenerateIFCGuidFrom( - GUIDUtil.CreateGUIDString(IFCEntityType.IfcRelDefinesByProperties, quantitySetName, elemHnd)); - ExporterUtil.CreateRelDefinesByProperties(file, quantityRelGuid, ownerHistory, null, null, - relatedObjects, quantity); - } + if (property == null) + { + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.LuminousFlux, valueType); + property = CreateLuminousFluxPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } + + return property; } /// - /// Creates the shared beam, column and member QTO values. + /// Create a LuminousIntensity measure property from the element's parameter. /// - /// The exporter. - /// The element handle. - /// The element. - /// The IFCExportBodyParams containing the appropriate data. - public static void CreateBeamColumnMemberBaseQuantities(ExporterIFC exporterIFC, IFCAnyHandle elemHandle, Element element, IFCExportBodyParams ecData) + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateLuminousIntensityPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) { - FamilyTypeInfo ifcTypeInfo = new FamilyTypeInfo() { extraParams = ecData }; - CreateBeamColumnBaseQuantities(exporterIFC, elemHandle, element, ifcTypeInfo, null); + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.LuminousIntensity, valueType); + IFCAnyHandle property = CreateLuminousIntensityPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); + + if (property == null) + { + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.LuminousIntensity, valueType); + property = CreateLuminousIntensityPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); + } + + return property; } /// - /// Creates property sets for Revit groups and parameters, if export options is set. + /// Create a Mass measure property from the element's parameter. /// - /// The ExporterIFC. - /// The Element. - /// The collection of IFCAnyHandles to relate properties to. - /// Forces properties creation even if 'Export internal properties' is unchecked. - public static void CreateInternalRevitPropertySets(ExporterIFC exporterIFC, Element element, - ISet elementSets, bool forceCreate) + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateMassPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) { - if (exporterIFC == null || element == null || - (!ExporterCacheManager.ExportOptionsCache.PropertySetOptions.ExportInternalRevit && !forceCreate)) - return; - - // We will allow creating internal Revit property sets for element types with no associated element handles. - if (((elementSets?.Count ?? 0) == 0) && !(element is ElementType)) - return; + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.Mass, valueType); + IFCAnyHandle property = CreateMassPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); - IFCFile file = exporterIFC.GetFile(); - - ElementId typeId = element.GetTypeId(); - Element elementType = element.Document.GetElement(typeId); - int whichStart = elementType != null ? 0 : (element is ElementType ? 1 : 0); - if (whichStart == 1) + if (property == null) { - typeId = element.Id; - elementType = element as ElementType; + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.Mass, valueType); + property = CreateMassPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - SortedDictionary)>[] propertySets; - propertySets = new SortedDictionary)>[2]; - propertySets[0] = new SortedDictionary)>(); - propertySets[1] = new SortedDictionary)>(); + return property; + } - // pass through: element and element type. If the element is a ElementType, there will only be one pass. - for (int which = whichStart; which < 2; which++) - { - Element whichElement = (which == 0) ? element : elementType; - if (whichElement == null) - continue; - - // If we have already processed this element, just add the new - // IFC entities. - if (ExporterCacheManager.CreatedInternalPropertySets.TryAppend(whichElement.Id, elementSets)) - continue; + /// + /// Create a MassDensity measure property from the element's parameter. + /// + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateMassDensityPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) + { + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.MassDensity, valueType); + IFCAnyHandle property = CreateMassDensityPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); - ElementId whichElementId = whichElement.Id; + if (property == null) + { + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.MassDensity, valueType); + property = CreateMassDensityPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); + } - bool createType = (which == 1); - if (createType) - { - if (ExporterCacheManager.TypePropertyInfoCache.HasTypeProperties(typeId)) - continue; - } + return property; + } - IDictionary parameterElementCache = - ParameterUtil.GetNonIFCParametersForElement(whichElementId); - if (parameterElementCache == null) - continue; + /// + /// Create a MassFlowRate measure property from the element's parameter. + /// + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateMassFlowRatePropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) + { + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.PipingMassPerTime, valueType); + IFCAnyHandle property = CreateMassFlowRatePropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); - foreach (KeyValuePair parameterElementGroup in parameterElementCache) - { - ForgeTypeId parameterGroup = new ForgeTypeId (parameterElementGroup.Key); - string groupName = LabelUtils.GetLabelForGroup(parameterGroup); + if (property == null) + { + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.PipingMassPerTime, valueType); + property = CreateMassFlowRatePropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); + } - // We are only going to append the "(Type)" suffix if we aren't also exporting the corresponding entity type. - // In general, we'd like to always export them entity type, regardles of whether it holds any geometry or not - it can hold - // at least the parameteric information. When this is acheived, when can get rid of this entirely. - // Unfortunately, IFC2x3 doesn't have types for all entities, so for IFC2x3 at least this will continue to exist - // in some fashion. - // There was a suggestion in SourceForge that we could "merge" the instance/type property sets in the cases where we aren't - // creating an entity type, and in the cases where two properties had the same name, use the instance over type. - // However, given our intention to generally export all types, this seems like a lot of work for diminishing returns. - if (whichElement is ElementType) - if (which == 1 && !ExporterCacheManager.ElementTypeToHandleCache.IsRegistered(whichElement as ElementType)) - groupName += Properties.Resources.PropertySetTypeSuffix; + return property; + } - HashSet currPropertiesForGroup = new HashSet(); - propertySets[which][parameterElementGroup.Key] = (groupName, currPropertiesForGroup); + /// + /// Create a MassPerLength measure property from the element's parameter. + /// + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateMassPerLengthPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) + { + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.MassPerUnitLength, valueType); + IFCAnyHandle property = CreateMassPerLengthPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); - foreach (Parameter parameter in parameterElementGroup.Value.ParameterCache.Values) - { - if (!parameter.HasValue) - continue; + if (property == null) + { + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.MassPerUnitLength, valueType); + property = CreateMassPerLengthPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); + } - Definition parameterDefinition = parameter.Definition; - if (parameterDefinition == null) - continue; + return property; + } - string parameterCaption = parameterDefinition.Name; + /// + /// Create a ModulusOfElasticity measure property from the element's parameter. + /// + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateModulusOfElasticityPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) + { + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.Stress, valueType); + IFCAnyHandle property = CreateModulusOfElasticityPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); - switch (parameter.StorageType) - { - case StorageType.None: - break; - case StorageType.Integer: - { - int value = parameter.AsInteger(); - string valueAsString = parameter.AsValueString(); + if (property == null) + { + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.Stress, valueType); + property = CreateModulusOfElasticityPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); + } - // YesNo or actual integer? - if (parameterDefinition.GetDataType() == SpecTypeId.Boolean.YesNo) - { - currPropertiesForGroup.Add(CreateBooleanPropertyFromCache(file, parameterCaption, value != 0, PropertyValueType.SingleValue)); - } - else if (parameterDefinition.GetDataType().Empty() && (valueAsString != null)) - { - // This is probably an internal enumerated type that should be exported as a string. - currPropertiesForGroup.Add(CreateIdentifierPropertyFromCache(file, parameterCaption, valueAsString, PropertyValueType.SingleValue)); - } - else - { - currPropertiesForGroup.Add(CreateIntegerPropertyFromCache(file, parameterCaption, value, PropertyValueType.SingleValue)); - } - break; - } - case StorageType.Double: - { - double value = parameter.AsDouble(); - IFCAnyHandle propertyHandle = CreateRealPropertyBasedOnParameterType(file, parameter, parameterCaption, value, PropertyValueType.SingleValue); + return property; + } - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propertyHandle)) - currPropertiesForGroup.Add(propertyHandle); - break; - } - case StorageType.String: - { - string value = parameter.AsString(); - if (!string.IsNullOrEmpty(value)) - currPropertiesForGroup.Add(CreateTextPropertyFromCache(file, parameterCaption, value, PropertyValueType.SingleValue)); - break; - } - case StorageType.ElementId: - { - if (parameter.AsElementId() != ElementId.InvalidElementId) - { - string valueString = parameter.AsValueString(); - currPropertiesForGroup.Add(CreateLabelPropertyFromCache(file, parameter.Id, parameterCaption, valueString, PropertyValueType.SingleValue, true, null)); - } - break; - } - } - } - } - } + /// + /// Create a MoistureDiffusivity measure property from the element's parameter. + /// + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateMoistureDiffusivityPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) + { + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.Diffusivity, valueType); + IFCAnyHandle property = CreateMoistureDiffusivityPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); - for (int which = whichStart; which < 2; which++) + if (property == null) { - Element whichElement = (which == 0) ? element : elementType; - if (whichElement == null) - continue; + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.Diffusivity, valueType); + property = CreateMoistureDiffusivityPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); + } - HashSet createdPropertySets = new HashSet(); + return property; + } - int size = propertySets[which].Count; - if (size == 0) - { - ExporterCacheManager.TypePropertyInfoCache.AddNewElementHandles(typeId, elementSets); - continue; - } + /// + /// Create a MomentOfInertia measure property from the element's parameter. + /// + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateMomentOfInertiaPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) + { + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.MomentOfInertia, valueType); + IFCAnyHandle property = CreateMomentOfInertiaPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); - bool materialProperties = element is Material; - foreach (KeyValuePair)> currPropertySet in propertySets[which]) - { - if (currPropertySet.Value.Item2.Count == 0) - continue; + if (property == null) + { + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.MomentOfInertia, valueType); + property = CreateMomentOfInertiaPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); + } - if (materialProperties) - { - MaterialPropertiesUtil.ExportGenericMaterialPropertySet(file, elementSets?.ToList().First(), currPropertySet.Value.Item2, null, currPropertySet.Value.Item1); - } - else - { - string psetGUID = GUIDUtil.GenerateIFCGuidFrom( - GUIDUtil.CreateGUIDString(whichElement, "IfcPropertySet: " + currPropertySet.Key.ToString())); + return property; + } - IFCAnyHandle propertySet = IFCInstanceExporter.CreatePropertySet(file, psetGUID, - ExporterCacheManager.OwnerHistoryHandle, currPropertySet.Value.Item1, null, - currPropertySet.Value.Item2); - createdPropertySets.Add(propertySet); - } - } + /// + /// Create a NormalisedRatio measure property from the element's parameter. + /// + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateNormalisedRatioPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) + { + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.Number, valueType); + IFCAnyHandle property = CreateNormalisedRatioPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); - // Don't need to create relations for material properties - if (!materialProperties) - { - if (which == 0) - ExporterCacheManager.CreatedInternalPropertySets.Add(whichElement.Id, createdPropertySets, elementSets); - else - ExporterCacheManager.TypePropertyInfoCache.AddNewTypeProperties(typeId, createdPropertySets, elementSets); - } + if (property == null) + { + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.Number, valueType); + property = CreateNormalisedRatioPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } + + return property; } /// - /// Get a unit type of parameter. - /// IFCUnit for each one. + /// Create a Numeric measure property from the element's parameter. /// - /// The parameter. - /// The parameter unit type. - public static ForgeTypeId GetParameterUnitType(Parameter parameter) + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateNumericPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) { - ForgeTypeId parameterUnitType = null; + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.Number, valueType); + IFCAnyHandle property = CreateNumericPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); - try - { - parameterUnitType = parameter?.GetUnitTypeId(); - } - catch + if (property == null) { - // GetUnitTypeId() can fail for reasons that don't seem to be knowable in - // advance, so we won't scale value in these cases. + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.Number, valueType); + property = CreateNumericPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - return parameterUnitType; + return property; } /// - /// Creates property from real parameter. - /// There are many different ParameterTypes in Revit that share the same unit dimensions, but that - /// have potentially different display units (e.g. Bar Diameter could be in millimeters while the project - /// default length parameter is in meters.) For now, we will only support one unit type. At a later - /// point, we could decide to have different caches for each parameter type, and export a different - /// IFCUnit for each one. + /// Create a PlaneAngle measure property from the element's parameter. /// /// The IFC file. - /// The parameter. - /// The name of the property. - /// The value of the property. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. /// The value type of the property. /// The created property handle. - public static IFCAnyHandle CreateRealPropertyBasedOnParameterType(IFCFile file, Parameter parameter, string propertyName, double propertyValue, PropertyValueType valueType) + public static IFCAnyHandle CreatePlaneAnglePropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) { - if (parameter == null) - return null; + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.Angle, valueType); + IFCAnyHandle property = CreatePlaneAnglePropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); - ForgeTypeId type = parameter.Definition?.GetDataType(); - ForgeTypeId fallbackUnitType = GetParameterUnitType(parameter); + if (property == null) + { + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.Angle, valueType); + property = CreatePlaneAnglePropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); + } - return CreateRealPropertyByType(file, type, propertyName, propertyValue, valueType, fallbackUnitType); + return property; } /// - /// Creates property from real parameter. + /// Create a PlanarForce measure property from the element's parameter. /// /// The IFC file. - /// The type of the parameter. - /// The name of the property. - /// The value of the property. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. /// The value type of the property. - /// The optional unit type. Can be used for scaling in final case /// The created property handle. - public static IFCAnyHandle CreateRealPropertyByType(IFCFile file, ForgeTypeId parameterType, string propertyName, double propertyValue, PropertyValueType valueType, ForgeTypeId fallbackUnitType = null) + public static IFCAnyHandle CreatePlanarForcePropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) { - IFCAnyHandle propertyHandle = null; + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.AreaForce, valueType); + IFCAnyHandle property = CreatePlanarForcePropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); - if (parameterType == SpecTypeId.Acceleration) + if (property == null) { - double scaledValue = UnitUtil.ScaleAcceleration(propertyValue); - propertyHandle = CreateAccelerationMeasureProperty(file, propertyName, - scaledValue, valueType); + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.AreaForce, valueType); + property = CreatePlanarForcePropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - else if (parameterType == SpecTypeId.Energy || - parameterType == SpecTypeId.HvacEnergy) - { - double scaledValue = UnitUtil.ScaleEnergy(propertyValue); - propertyHandle = CreateEnergyMeasureProperty(file, propertyName, - scaledValue, valueType); - } - else if (parameterType == SpecTypeId.LinearMoment) + + return property; + } + + /// + /// Create a PositiveLength measure property from the element's parameter. + /// + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreatePositiveLengthPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) + { + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.Length, valueType); + IFCAnyHandle property = CreatePositiveLengthPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); + + if (property == null) { - double scaledValue = UnitUtil.ScaleLinearMoment(propertyValue); - propertyHandle = CreateLinearMomentMeasureProperty(file, propertyName, - scaledValue, valueType); + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.Length, valueType); + property = CreatePositiveLengthPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - else if (parameterType == SpecTypeId.MassPerUnitLength || - parameterType == SpecTypeId.PipeMassPerUnitLength) + + return property; + } + + /// + /// Create a PositiveRatio measure property from the element's parameter. + /// + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreatePositiveRatioPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) + { + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.Number, valueType); + IFCAnyHandle property = CreatePositiveRatioPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); + + if (property == null) { - double scaledValue = UnitUtil.ScaleMassPerLength(propertyValue); - propertyHandle = CreateMassPerLengthMeasureProperty(file, propertyName, - scaledValue, valueType); + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.Number, valueType); + property = CreatePositiveRatioPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - else if (parameterType == SpecTypeId.Moment) + + return property; + } + + /// + /// Create a PositivePlaneAngle measure property from the element's parameter. + /// + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreatePositivePlaneAnglePropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) + { + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.Angle, valueType); + IFCAnyHandle property = CreatePositivePlaneAnglePropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); + + if (property == null) { - double scaledValue = UnitUtil.ScaleTorque(propertyValue); - propertyHandle = CreateTorqueMeasureProperty(file, propertyName, - scaledValue, valueType); + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.Angle, valueType); + property = CreatePositivePlaneAnglePropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - else if (parameterType == SpecTypeId.PointSpringCoefficient) + + return property; + } + + /// + /// Create a Power measure property from the element's parameter. + /// + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreatePowerPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) + { + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.HvacPower, valueType); + IFCAnyHandle property = CreatePowerPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); + + if (property == null) { - double scaledValue = UnitUtil.ScaleLinearStiffness(propertyValue); - propertyHandle = CreateLinearStiffnessMeasureProperty(file, propertyName, - scaledValue, valueType); + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.HvacPower, valueType); + property = CreatePowerPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - else if (parameterType == SpecTypeId.Pulsation) + + return property; + } + + /// + /// Create a Pressure measure property from the element's parameter. + /// + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreatePressurePropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) + { + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.HvacPressure, valueType); + IFCAnyHandle property = CreatePressurePropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); + + if (property == null) { - double scaledValue = UnitUtil.ScaleAngularVelocity(propertyValue); - propertyHandle = CreateAngularVelocityMeasureProperty(file, propertyName, - scaledValue, valueType); + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.HvacPressure, valueType); + property = CreatePressurePropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - else if (parameterType == SpecTypeId.ThermalResistance) + + return property; + } + + /// + /// Create a Ratio measure property from the element's parameter. + /// + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateRatioPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) + { + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.Number, valueType); + IFCAnyHandle property = CreateRatioPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); + + if (property == null) { - double scaledValue = UnitUtil.ScaleThermalResistance(propertyValue); - propertyHandle = CreateThermalResistanceMeasureProperty(file, propertyName, - scaledValue, valueType); + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.Number, valueType); + property = CreateRatioPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - else if (parameterType == SpecTypeId.WarpingConstant) + + return property; + } + + /// + /// Create a Real measure property from the element's parameter. + /// + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateRealPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) + { + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.Number, valueType); + IFCAnyHandle property = CreateRealPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); + + if (property == null) { - double scaledValue = UnitUtil.ScaleWarpingConstant(propertyValue); - propertyHandle = CreateWarpingConstantMeasureProperty(file, propertyName, - scaledValue, valueType); + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.Number, valueType); + property = CreateRealPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - else if (parameterType == SpecTypeId.Angle || - parameterType == SpecTypeId.Rotation || - parameterType == SpecTypeId.RotationAngle) + + return property; + } + + /// + /// Create a RotationalFrequency measure property from the element's parameter. + /// + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateRotationalFrequencyPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) + { + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.AngularSpeed, valueType); + IFCAnyHandle property = CreateRotationalFrequencyPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); + + if (property == null) { - propertyHandle = CreatePlaneAngleMeasurePropertyFromCache(file, propertyName, - UnitUtil.ScaleAngle(propertyValue), valueType); + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.AngularSpeed, valueType); + property = CreateRotationalFrequencyPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - else if (parameterType == SpecTypeId.Slope || - parameterType == SpecTypeId.HvacSlope || - parameterType == SpecTypeId.PipingSlope || - parameterType == SpecTypeId.DemandFactor || - parameterType == SpecTypeId.Factor) + + return property; + } + + /// + /// Create a SoundPower measure property from the element's parameter. + /// + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateSoundPowerPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) + { + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.Wattage, valueType); + IFCAnyHandle property = CreateSoundPowerPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); + + if (property == null) { - propertyHandle = CreatePositiveRatioMeasureProperty(file, propertyName, - propertyValue, valueType); + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.Wattage, valueType); + property = CreateSoundPowerPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - else if (parameterType == SpecTypeId.Area || - parameterType == SpecTypeId.CrossSection || - parameterType == SpecTypeId.ReinforcementArea || - parameterType == SpecTypeId.SectionArea) + + return property; + } + + /// + /// Create a SoundPressure measure property from the element's parameter. + /// + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateSoundPressurePropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) + { + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.HvacPressure, valueType); + IFCAnyHandle property = CreateSoundPressurePropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); + + if (property == null) { - double scaledValue = UnitUtil.ScaleArea(propertyValue); - propertyHandle = CreateAreaMeasureProperty(file, propertyName, - scaledValue, valueType); + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.HvacPressure, valueType); + property = CreateSoundPressurePropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - else if (parameterType == SpecTypeId.BarDiameter || - parameterType == SpecTypeId.CrackWidth || - parameterType == SpecTypeId.Displacement || - parameterType == SpecTypeId.Distance || - parameterType == SpecTypeId.CableTraySize || - parameterType == SpecTypeId.ConduitSize || - parameterType == SpecTypeId.Length || - parameterType == SpecTypeId.DuctInsulationThickness || - parameterType == SpecTypeId.DuctLiningThickness || - parameterType == SpecTypeId.DuctSize || - parameterType == SpecTypeId.HvacRoughness || - parameterType == SpecTypeId.PipeDimension || - parameterType == SpecTypeId.PipeInsulationThickness || - parameterType == SpecTypeId.PipeSize || - parameterType == SpecTypeId.PipingRoughness || - parameterType == SpecTypeId.ReinforcementCover || - parameterType == SpecTypeId.ReinforcementLength || - parameterType == SpecTypeId.ReinforcementSpacing || - parameterType == SpecTypeId.SectionDimension || - parameterType == SpecTypeId.SectionProperty || - parameterType == SpecTypeId.WireDiameter || - parameterType == SpecTypeId.SurfaceAreaPerUnitLength) + + return property; + } + + /// + /// Create a SpecificHeatCapacity measure property from the element's parameter. + /// + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateSpecificHeatCapacityPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) + { + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.SpecificHeat, valueType); + IFCAnyHandle property = CreateSpecificHeatCapacityPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); + + if (property == null) { - propertyHandle = CreateLengthMeasurePropertyFromCache(file, propertyName, - UnitUtil.ScaleLength(propertyValue), valueType); + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.SpecificHeat, valueType); + property = CreateSpecificHeatCapacityPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - else if (parameterType == SpecTypeId.ColorTemperature) + + return property; + } + + /// + /// Create a ThermalConductivity measure property from the element's parameter. + /// + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateThermalConductivityPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) + { + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.ThermalConductivity, valueType); + IFCAnyHandle property = CreateThermalConductivityPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); + + if (property == null) { - double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.ColorTemperature, propertyValue); - propertyHandle = CreateColorTemperaturePropertyFromValue(file, propertyName, scaledValue); + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.ThermalConductivity, valueType); + property = CreateThermalConductivityPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - else if (parameterType == SpecTypeId.Currency) + + return property; + } + + /// + /// Create a ThermalExpansionCoefficient measure property from the element's parameter. + /// + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateThermalExpansionCoefficientPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) + { + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.ThermalExpansionCoefficient, valueType); + IFCAnyHandle property = CreateThermalExpansionCoefficientPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); + + if (property == null) { - IFCData currencyData = ExporterCacheManager.UnitsCache.ContainsKey("CURRENCY") ? - IFCDataUtil.CreateAsMeasure(propertyValue, "IfcMonetaryMeasure") : - IFCDataUtil.CreateAsMeasure(propertyValue, "IfcReal"); - propertyHandle = CreateCommonProperty(file, propertyName, currencyData, - valueType, null); + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.ThermalExpansionCoefficient, valueType); + property = CreateThermalExpansionCoefficientPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - else if (parameterType == SpecTypeId.ApparentPower || - parameterType == SpecTypeId.ElectricalPower || - parameterType == SpecTypeId.Wattage || - parameterType == SpecTypeId.CoolingLoad || - parameterType == SpecTypeId.HeatGain || - parameterType == SpecTypeId.HeatingLoad || - parameterType == SpecTypeId.HvacPower) + + return property; + } + + /// + /// Create a ThermalResistance measure property from the element's parameter. + /// + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateThermalResistancePropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) + { + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.ThermalResistance, valueType); + IFCAnyHandle property = CreateThermalResistancePropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); + + if (property == null) { - double scaledValue = UnitUtil.ScalePower(propertyValue); - propertyHandle = CreatePowerProperty(file, propertyName, - scaledValue, valueType); + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.ThermalResistance, valueType); + property = CreateThermalResistancePropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - else if (parameterType == SpecTypeId.Current) + + return property; + } + + /// + /// Create a ThermalTransmittance measure property from the element's parameter. + /// + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateThermalTransmittancePropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) + { + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.HeatTransferCoefficient, valueType); + IFCAnyHandle property = CreateThermalTransmittancePropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); + + if (property == null) { - double scaledValue = UnitUtil.ScaleElectricCurrent(propertyValue); - propertyHandle = ElectricalCurrentPropertyUtil.CreateElectricalCurrentMeasureProperty(file, propertyName, - scaledValue, valueType); + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.HeatTransferCoefficient, valueType); + property = CreateThermalTransmittancePropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - else if (parameterType == SpecTypeId.Diffusivity) - { - double scaledValue = UnitUtil.ScaleMoistureDiffusivity(propertyValue); - IFCData moistureDiffusivityData = IFCDataUtil.CreateAsMoistureDiffusivityMeasure(scaledValue); - propertyHandle = CreateCommonProperty(file, propertyName, moistureDiffusivityData, - valueType, null); - } - else if (parameterType == SpecTypeId.Efficacy) - { - double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.Efficacy, propertyValue); - propertyHandle = CreateElectricalEfficacyPropertyFromValue(file, propertyName, scaledValue); - } - else if (parameterType == SpecTypeId.ElectricalFrequency || - parameterType == SpecTypeId.StructuralFrequency) - { - propertyHandle = FrequencyPropertyUtil.CreateFrequencyProperty(file, propertyName, - propertyValue, valueType); - } - else if (parameterType == SpecTypeId.Illuminance) - { - double scaledValue = UnitUtil.ScaleIlluminance(propertyValue); - propertyHandle = CreateIlluminanceProperty(file, propertyName, - scaledValue, valueType); - } - else if (parameterType == SpecTypeId.LuminousFlux) - { - double scaledValue = UnitUtil.ScaleLuminousFlux(propertyValue); - propertyHandle = CreateLuminousFluxMeasureProperty(file, propertyName, - scaledValue, valueType); - } - else if (parameterType == SpecTypeId.LuminousIntensity) - { - double scaledValue = UnitUtil.ScaleLuminousIntensity(propertyValue); - propertyHandle = CreateLuminousIntensityProperty(file, propertyName, - scaledValue, valueType); - } - else if (parameterType == SpecTypeId.ElectricalPotential) - { - double scaledValue = UnitUtil.ScaleElectricVoltage(propertyValue); - propertyHandle = ElectricVoltagePropertyUtil.CreateElectricVoltageMeasureProperty(file, propertyName, - scaledValue, valueType); - } - else if (parameterType == SpecTypeId.ElectricalTemperature || - parameterType == SpecTypeId.HvacTemperature || - parameterType == SpecTypeId.PipingTemperature) - { - double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.HvacTemperature, propertyValue); - IFCData temperatureData = IFCDataUtil.CreateAsMeasure(scaledValue, "IfcThermodynamicTemperatureMeasure"); - propertyHandle = CreateCommonProperty(file, propertyName, temperatureData, - valueType, null); - } - else if (parameterType == SpecTypeId.HeatTransferCoefficient) - { - double scaledValue = UnitUtil.ScaleThermalTransmittance(propertyValue); - IFCData temperatureData = IFCDataUtil.CreateAsMeasure(scaledValue, "IfcThermalTransmittanceMeasure"); - propertyHandle = CreateCommonProperty(file, propertyName, temperatureData, - valueType, null); - } - else if (parameterType == SpecTypeId.Force || - parameterType == SpecTypeId.Weight) - { - double scaledValue = UnitUtil.ScaleForce(propertyValue); - propertyHandle = CreateForceProperty(file, propertyName, - scaledValue, valueType); - } - else if (parameterType == SpecTypeId.AreaForce) - { - double scaledValue = UnitUtil.ScalePlanarForce(propertyValue); - propertyHandle = CreatePlanarForceProperty(file, propertyName, - scaledValue, valueType); - } - else if (parameterType == SpecTypeId.LinearForce || - parameterType == SpecTypeId.WeightPerUnitLength) - { - double scaledValue = UnitUtil.ScaleLinearForce(propertyValue); - propertyHandle = CreateLinearForceProperty(file, propertyName, - scaledValue, valueType); - } - else if (parameterType == SpecTypeId.AirFlow || - parameterType == SpecTypeId.Flow) - { - double scaledValue = UnitUtil.ScaleVolumetricFlowRate(propertyValue); - propertyHandle = CreateVolumetricFlowRateMeasureProperty(file, propertyName, - scaledValue, valueType); - } - else if (parameterType == SpecTypeId.HvacFriction) - { - double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.HvacFriction, propertyValue); - IFCData frictionData = IFCDataUtil.CreateAsMeasure(scaledValue, "IfcReal"); - propertyHandle = CreateCommonProperty(file, propertyName, frictionData, - valueType, "FRICTIONLOSS"); - } - else if (parameterType == SpecTypeId.HvacPressure || - parameterType == SpecTypeId.PipingPressure || - parameterType == SpecTypeId.Stress) - { - double scaledValue = UnitUtil.ScalePressure(propertyValue); - IFCData pressureData = IFCDataUtil.CreateAsMeasure(scaledValue, "IfcPressureMeasure"); - propertyHandle = CreateCommonProperty(file, propertyName, pressureData, - valueType, null); - } - else if (parameterType == SpecTypeId.HvacVelocity || - parameterType == SpecTypeId.PipingVelocity || - parameterType == SpecTypeId.StructuralVelocity || - parameterType == SpecTypeId.Speed) - { - double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.HvacVelocity, propertyValue); - IFCData linearVelocityData = IFCDataUtil.CreateAsMeasure(scaledValue, "IfcLinearVelocityMeasure"); - propertyHandle = CreateCommonProperty(file, propertyName, linearVelocityData, - valueType, null); - } - else if (parameterType == SpecTypeId.Mass || - parameterType == SpecTypeId.PipingMass) - { - double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.Mass, propertyValue); - IFCData massData = IFCDataUtil.CreateAsMeasure(scaledValue, "IfcMassMeasure"); - propertyHandle = CreateCommonProperty(file, propertyName, massData, - valueType, null); - } - else if (parameterType == SpecTypeId.MassDensity || - parameterType == SpecTypeId.HvacDensity) - { - double scaledValue = UnitUtil.ScaleMassDensity(propertyValue); - IFCData massDensityData = IFCDataUtil.CreateAsMeasure(scaledValue, "IfcMassDensityMeasure"); - propertyHandle = CreateCommonProperty(file, propertyName, massDensityData, - valueType, null); - } - else if (parameterType == SpecTypeId.PipingDensity) - { - double scaledValue = UnitUtil.ScaleIonConcentration(propertyValue); - IFCData ionConcentrationData = IFCDataUtil.CreateAsIonConcentrationMeasure(scaledValue); - propertyHandle = CreateCommonProperty(file, propertyName, ionConcentrationData, - valueType, null); - } - else if (parameterType == SpecTypeId.MomentOfInertia) - { - double scaledValue = UnitUtil.ScaleMomentOfInertia(propertyValue); - IFCData momentOfInertiaData = IFCDataUtil.CreateAsMomentOfInertiaMeasure(scaledValue); - propertyHandle = CreateCommonProperty(file, propertyName, momentOfInertiaData, - valueType, null); - } - else if (parameterType == SpecTypeId.Number) - { - propertyHandle = CreateRealPropertyFromCache(file, propertyName, propertyValue, valueType); - } - else if (parameterType == SpecTypeId.PipingVolume || - parameterType == SpecTypeId.ReinforcementVolume || - parameterType == SpecTypeId.SectionModulus || - parameterType == SpecTypeId.Volume) - { - double scaledValue = UnitUtil.ScaleVolume(propertyValue); - propertyHandle = CreateVolumeMeasureProperty(file, propertyName, - scaledValue, valueType); - } - else if (parameterType == SpecTypeId.PipingMassPerTime || - parameterType == SpecTypeId.HvacMassPerTime) - { - double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.PipingMassPerTime, propertyValue); - IFCData massFlowRateData = IFCDataUtil.CreateAsMeasure(scaledValue, "IfcMassFlowRateMeasure"); - propertyHandle = CreateCommonProperty(file, propertyName, massFlowRateData, - valueType, null); - } - else if (parameterType == SpecTypeId.AngularSpeed) - { - double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.AngularSpeed, propertyValue); - IFCData rotationalFrequencyData = IFCDataUtil.CreateAsMeasure(scaledValue, "IfcRotationalFrequencyMeasure"); - propertyHandle = CreateCommonProperty(file, propertyName, rotationalFrequencyData, - valueType, null); - } - else if (parameterType == SpecTypeId.ThermalConductivity) - { - double scaledValue = UnitUtil.ScaleThermalConductivity(propertyValue); - IFCData thermalConductivityData = IFCDataUtil.CreateAsThermalConductivityMeasure(scaledValue); - propertyHandle = CreateCommonProperty(file, propertyName, thermalConductivityData, - valueType, null); - } - else if (parameterType == SpecTypeId.SpecificHeat) - { - double scaledValue = UnitUtil.ScaleSpecificHeatCapacity(propertyValue); - IFCData specificHeatData = IFCDataUtil.CreateAsSpecificHeatCapacityMeasure(scaledValue); - propertyHandle = CreateCommonProperty(file, propertyName, specificHeatData, - valueType, null); - } - else if (parameterType == SpecTypeId.Permeability) + + return property; + } + + /// + /// Create a ThermodynamicTemperature measure property from the element's parameter. + /// + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateThermodynamicTemperaturePropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) + { + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.HvacTemperature, valueType); + IFCAnyHandle property = CreateThermodynamicTemperaturePropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); + + if (property == null) { - double scaledValue = UnitUtil.ScaleVaporPermeability(propertyValue); - IFCData permeabilityData = IFCDataUtil.CreateAsVaporPermeabilityMeasure(scaledValue); - propertyHandle = CreateCommonProperty(file, propertyName, permeabilityData, - valueType, null); + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.HvacTemperature, valueType); + property = CreateThermodynamicTemperaturePropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - else if (parameterType == SpecTypeId.HvacViscosity || - parameterType == SpecTypeId.PipingViscosity) + + return property; + } + + /// + /// Create a VaporPermeability measure property from the element's parameter. + /// + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateVaporPermeabilityPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) + { + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.Permeability, valueType); + IFCAnyHandle property = CreateVaporPermeabilityPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); + + if (property == null) { - double scaledValue = UnitUtil.ScaleDynamicViscosity(propertyValue); - IFCData hvacViscosityData = IFCDataUtil.CreateAsDynamicViscosityMeasure(scaledValue); - propertyHandle = CreateCommonProperty(file, propertyName, hvacViscosityData, - valueType, null); + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.Permeability, valueType); + property = CreateVaporPermeabilityPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - else if (parameterType == SpecTypeId.ThermalExpansionCoefficient) + + return property; + } + + /// + /// Create a Volume measure property from the element's parameter. + /// + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateVolumePropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) + { + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.Volume, valueType); + IFCAnyHandle property = CreateVolumePropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); + + if (property == null) { - double scaledValue = UnitUtil.ScaleThermalExpansionCoefficient(propertyValue); - IFCData thermalExpansionCoefficientData = IFCDataUtil.CreateAsThermalExpansionCoefficientMeasure(scaledValue); - propertyHandle = CreateCommonProperty(file, propertyName, thermalExpansionCoefficientData, - valueType, null); + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.Volume, valueType); + property = CreateVolumePropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - else if (parameterType == SpecTypeId.ElectricalResistivity) + + return property; + } + + /// + /// Create a VolumetricFlowRate measure property from the element's parameter. + /// + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateVolumetricFlowRatePropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) + { + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.AirFlow, valueType); + IFCAnyHandle property = CreateVolumetricFlowRatePropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); + + if (property == null) { - double scaledValue = UnitUtil.ScaleDouble(SpecTypeId.ElectricalResistivity, propertyValue); - IFCData electricalResistivityData = IFCDataUtil.CreateAsMeasure(scaledValue, "IfcReal"); - propertyHandle = CreateCommonProperty(file, propertyName, electricalResistivityData, - valueType, "ELECTRICALRESISTIVITY"); + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.AirFlow, valueType); + property = CreateVolumetricFlowRatePropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - else if (parameterType == SpecTypeId.SpecificHeatOfVaporization) + + return property; + } + + /// + /// Create a Torque measure property from the element's parameter. + /// + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateTorquePropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) + { + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.Moment, valueType); + IFCAnyHandle property = CreateTorquePropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); + + if (property == null) { - double scaledValue = UnitUtil.ScaleHeatingValue(propertyValue); - IFCData heatingValueData = IFCDataUtil.CreateAsHeatingValueMeasure(scaledValue); - propertyHandle = CreateCommonProperty(file, propertyName, heatingValueData, - valueType, null); + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.Moment, valueType); + property = CreateTorquePropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - else if (parameterType == SpecTypeId.IsothermalMoistureCapacity) + + return property; + } + + /// + /// Create a WarpingConstant measure property from the element's parameter. + /// + /// The IFC file. + /// The Element. + /// The name of the parameter. + /// The name of the property. Also, the backup name of the parameter. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateWarpingConstantPropertyFromElement(IFCFile file, Element elem, string revitParameterName, + string ifcPropertyName, PropertyValueType valueType) + { + IList doubleValues = GetDoubleValuesFromParameterByType(elem, revitParameterName, SpecTypeId.WarpingConstant, valueType); + IFCAnyHandle property = CreateWarpingConstantPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); + + if (property == null) { - double scaledValue = UnitUtil.ScaleIsothermalMoistureCapacity(propertyValue); - IFCData isothermalMoistureCapacityData = IFCDataUtil.CreateAsIsothermalMoistureCapacityMeasure(scaledValue); - propertyHandle = CreateCommonProperty(file, propertyName, isothermalMoistureCapacityData, - valueType, null); + doubleValues = GetDoubleValuesFromParameterByType(elem, ifcPropertyName, SpecTypeId.WarpingConstant, valueType); + property = CreateWarpingConstantPropertyFromCache(file, ifcPropertyName, doubleValues, valueType, null); } - else if (parameterType == SpecTypeId.HvacPowerDensity) + + return property; + } + #endregion + + #region Create___PropertyFromCache + + /// Create property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The function to craete property. + /// The property type. + /// The created or cached property handle. + public static IFCAnyHandle CreateGenericPropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey, + Func, PropertyValueType, string, IFCAnyHandle> createProperty, PropertyType propertyType) + { + if ((values?.Count ?? 0) == 0) + return null; + + bool canCache = false; + double value = 0.0; + if (values.ElementAt(0) != null && valueType == PropertyValueType.SingleValue && string.IsNullOrEmpty(unitTypeKey)) { - double scaledValue = UnitUtil.ScaleHeatFluxDensity(propertyValue); - IFCData heatFluxDensityData = IFCDataUtil.CreateAsHeatFluxDensityMeasure(scaledValue); - propertyHandle = CreateCommonProperty(file, propertyName, heatFluxDensityData, - valueType, null); + bool isLengthProeprty = (propertyType == PropertyType.Length); + value = values.ElementAt(0).Value; + + double? adjustedValue = (isLengthProeprty) ? CanCacheDouble(UnitUtil.UnscaleLength(value)) : CanCacheDouble(value); + canCache = adjustedValue.HasValue; + if (canCache) + { + value = (isLengthProeprty) ? UnitUtil.UnscaleLength(adjustedValue.GetValueOrDefault()) : adjustedValue.GetValueOrDefault(); + values[0] = value; + } } - else if (parameterType == SpecTypeId.MassPerUnitArea && !ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4) + + IFCAnyHandle propertyHandle; + if (canCache) { - double scaledValue = UnitUtil.ScaleAreaDensity(propertyValue); - IFCData areaDensityData = IFCDataUtil.CreateAsAreaDensityMeasure(scaledValue); - propertyHandle = CreateCommonProperty(file, propertyName, areaDensityData, - valueType, null); + propertyHandle = ExporterCacheManager.PropertyInfoCache.GetDoubleChache(propertyType).Find(propertyName, value); + if (propertyHandle != null) + return propertyHandle; } - else if (parameterType == SpecTypeId.Time || - parameterType == SpecTypeId.Period) + + propertyHandle = createProperty(file, propertyName, values, valueType, unitTypeKey); + + if (canCache && !IFCAnyHandleUtil.IsNullOrHasNoValue(propertyHandle)) { - double scaledValue = UnitUtil.ScaleTime(propertyValue); - IFCData timeData = IFCDataUtil.CreateAsTimeMeasure(scaledValue); - propertyHandle = CreateCommonProperty(file, propertyName, timeData, - valueType, null); + ExporterCacheManager.PropertyInfoCache.GetDoubleChache(propertyType).Add(propertyName, value, propertyHandle); } - else - { - double scaledValue = propertyValue; - if (fallbackUnitType != null) - scaledValue = UnitUtils.ConvertFromInternalUnits(propertyValue, fallbackUnitType); - propertyHandle = CreateRealPropertyFromCache(file, propertyName, scaledValue, valueType); - } + return propertyHandle; + } + + + /// Create Area property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateAreaPropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateAreaProperty, PropertyType.Area); + } + + /// Create Acceleration property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateAccelerationPropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateAccelerationProperty, PropertyType.Acceleration); + } + + /// Create AngularVelocity property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateAngularVelocityPropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateAngularVelocityProperty, PropertyType.AngularVelocity); + } + + /// Create AreaDensity property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateAreaDensityPropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateAreaDensityProperty, PropertyType.AreaDensity); + } + + /// Create DynamicViscosity property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateDynamicViscosityPropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateDynamicViscosityProperty, PropertyType.DynamicViscosity); + } + + /// Create ElectricCurrent property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateElectricCurrentPropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateElectricCurrentProperty, PropertyType.ElectricCurrent); + } + + /// Create ElectricVoltage property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateElectricVoltagePropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateElectricVoltageProperty, PropertyType.ElectricVoltage); + } + + /// Create Energy property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateEnergyPropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateEnergyProperty, PropertyType.Energy); + } + + /// Create Force property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateForcePropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateForceProperty, PropertyType.Force); + } + + /// Create Frequency property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateFrequencyPropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateFrequencyProperty, PropertyType.Frequency); + } + + /// Create HeatingValue property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateHeatingValuePropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateHeatingValueProperty, PropertyType.HeatingValue); + } + + /// Create Illuminance property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateIlluminancePropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateIlluminanceProperty, PropertyType.Illuminance); + } + + /// Create IonConcentration property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateIonConcentrationPropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateIonConcentrationProperty, PropertyType.IonConcentration); + } + + /// Create IsothermalMoistureCapacity property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateIsothermalMoistureCapacityPropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateIsothermalMoistureCapacityProperty, PropertyType.IsothermalMoistureCapacity); + } + + /// Create HeatFluxDensity property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateHeatFluxDensityPropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateHeatFluxDensityProperty, PropertyType.HeatFluxDensity); + } + + /// Create Length property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateLengthPropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateLengthProperty, PropertyType.Length); + } + + /// Create LinearForce property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateLinearForcePropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateLinearForceProperty, PropertyType.LinearForce); + } + + /// Create LinearMoment property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateLinearMomentPropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateLinearMomentProperty, PropertyType.LinearMoment); + } + + /// Create LinearStiffness property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateLinearStiffnessPropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateLinearStiffnessProperty, PropertyType.LinearStiffness); + } + + /// Create LinearVelocity property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateLinearVelocityPropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateLinearVelocityProperty, PropertyType.LinearVelocity); + } + + /// Create LuminousFlux property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateLuminousFluxPropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateLuminousFluxProperty, PropertyType.LuminousFlux); + } + + /// Create LuminousIntensity property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateLuminousIntensityPropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateLuminousIntensityProperty, PropertyType.LuminousIntensity); + } + + /// Create Mass property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateMassPropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateMassProperty, PropertyType.Mass); + } + + /// Create MassDensity property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateMassDensityPropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateMassDensityProperty, PropertyType.MassDensity); + } + + /// Create MassFlowRate property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateMassFlowRatePropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateMassFlowRateProperty, PropertyType.MassFlowRate); + } + + /// Create MassPerLength property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateMassPerLengthPropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateMassPerLengthProperty, PropertyType.MassPerLength); + } + + /// Create ModulusOfElasticity property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateModulusOfElasticityPropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateModulusOfElasticityProperty, PropertyType.ModulusOfElasticity); + } + + /// Create MoistureDiffusivity property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateMoistureDiffusivityPropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateMoistureDiffusivityProperty, PropertyType.MoistureDiffusivity); + } + + /// Create MomentOfInertia property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateMomentOfInertiaPropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateMomentOfInertiaProperty, PropertyType.MomentOfInertia); + } + + /// Create NormalisedRatio property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateNormalisedRatioPropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateNormalisedRatioProperty, PropertyType.NormalisedRatio); + } + + /// Create Numeric property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateNumericPropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateNumericProperty, PropertyType.Numeric); + } + + /// Create PlaneAngle property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreatePlaneAnglePropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreatePlaneAngleProperty, PropertyType.PlaneAngle); + } + + /// Create PlanarForce property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreatePlanarForcePropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreatePlanarForceProperty, PropertyType.PlanarForce); + } + + /// Create PositiveLength property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreatePositiveLengthPropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreatePositiveLengthProperty, PropertyType.PositiveLength); + } + + /// Create PositiveRatio property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreatePositiveRatioPropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreatePositiveRatioProperty, PropertyType.PositiveRatio); + } + + /// Create PositivePlaneAngle property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreatePositivePlaneAnglePropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreatePositivePlaneAngleProperty, PropertyType.PositivePlaneAngle); + } + + /// Create Power property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreatePowerPropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreatePowerProperty, PropertyType.Power); + } + + /// Create Pressure property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreatePressurePropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreatePressureProperty, PropertyType.Pressure); + } + + /// Create Ratio property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateRatioPropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateRatioProperty, PropertyType.Ratio); + } + + /// Create Real property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateRealPropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateRealProperty, PropertyType.Real); + } + + /// Create RotationalFrequency property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateRotationalFrequencyPropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateRotationalFrequencyProperty, PropertyType.RotationalFrequency); + } + + /// Create SoundPower property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateSoundPowerPropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateSoundPowerProperty, PropertyType.SoundPower); + } + + /// Create SoundPressure property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateSoundPressurePropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateSoundPressureProperty, PropertyType.SoundPressure); + } + + /// Create SpecificHeatCapacity property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateSpecificHeatCapacityPropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateSpecificHeatCapacityProperty, PropertyType.SpecificHeatCapacity); + } + + /// Create ThermalConductivity property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateThermalConductivityPropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateThermalConductivityProperty, PropertyType.ThermalConductivity); + } + + /// Create ThermalExpansionCoefficient property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateThermalExpansionCoefficientPropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateThermalExpansionCoefficientProperty, PropertyType.ThermalExpansionCoefficient); + } + + /// Create ThermalResistance property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateThermalResistancePropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateThermalResistanceProperty, PropertyType.ThermalResistance); + } + + /// Create ThermalTransmittance property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateThermalTransmittancePropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateThermalTransmittanceProperty, PropertyType.ThermalTransmittance); + } + + /// Create ThermodynamicTemperature property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateThermodynamicTemperaturePropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateThermodynamicTemperatureProperty, PropertyType.ThermodynamicTemperature); + } + + /// Create VaporPermeability property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateVaporPermeabilityPropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateVaporPermeabilityProperty, PropertyType.VaporPermeability); + } + + /// Create Volume property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateVolumePropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateVolumeProperty, PropertyType.Volume); + } + + /// Create VolumetricFlowRate property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateVolumetricFlowRatePropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateVolumetricFlowRateProperty, PropertyType.VolumetricFlowRate); + } + + /// Create Torque property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateTorquePropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateTorqueProperty, PropertyType.Torque); + } + + /// Create WarpingConstant property, using a cached value if possible. + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created or cached property handle. + public static IFCAnyHandle CreateWarpingConstantPropertyFromCache(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericPropertyFromCache(file, propertyName, values, valueType, unitTypeKey, CreateWarpingConstantProperty, PropertyType.WarpingConstant); + } + + + #endregion + + #region Create___Property + + /// + /// Create property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The craete measure function. + /// The created property handle. + public static IFCAnyHandle CreateGenericProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, + string unitTypeKey, Func createMeasure) + { + if (values == null) + return null; + + List dataList = new List(); + foreach (var val in values) + dataList.Add(val.HasValue ? createMeasure(val.Value) : null); + return CreateCommonPropertyFromList(file, propertyName, dataList, valueType, unitTypeKey); + } + + /// + /// Create Area property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateAreaProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsAreaMeasure); + } + + /// + /// Create Acceleration property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateAccelerationProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsAccelerationMeasure); + } + + /// + /// Create AngularVelocity property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateAngularVelocityProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsAngularVelocityMeasure); + } + + /// + /// Create AreaDensity property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateAreaDensityProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsAreaDensityMeasure); + } + + /// + /// Create DynamicViscosity property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateDynamicViscosityProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsDynamicViscosityMeasure); + } + + /// + /// Create ElectricCurrent property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateElectricCurrentProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsElectricCurrentMeasure); + } + + /// + /// Create ElectricVoltage property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateElectricVoltageProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsElectricVoltageMeasure); + } + + /// + /// Create Energy property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateEnergyProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsEnergyMeasure); + } + + /// + /// Create Force property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateForceProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsForceMeasure); + } + + /// + /// Create Frequency property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateFrequencyProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsFrequencyMeasure); + } + + /// + /// Create HeatingValue property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateHeatingValueProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsHeatingValueMeasure); + } + + /// + /// Create Illuminance property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateIlluminanceProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsIlluminanceMeasure); + } + + /// + /// Create IonConcentration property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateIonConcentrationProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsIonConcentrationMeasure); + } + + /// + /// Create IsothermalMoistureCapacity property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateIsothermalMoistureCapacityProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsIsothermalMoistureCapacityMeasure); + } + + /// + /// Create HeatFluxDensity property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateHeatFluxDensityProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsHeatFluxDensityMeasure); + } + + /// + /// Create Length property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateLengthProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsLengthMeasure); + } + + /// + /// Create LinearForce property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateLinearForceProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsLinearForceMeasure); + } + + /// + /// Create LinearMoment property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateLinearMomentProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsLinearMomentMeasure); + } + + /// + /// Create LinearStiffness property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateLinearStiffnessProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsLinearStiffnessMeasure); + } + + /// + /// Create LinearVelocity property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateLinearVelocityProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsLinearVelocityMeasure); + } + + /// + /// Create LuminousFlux property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateLuminousFluxProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsLuminousFluxMeasure); + } + + /// + /// Create LuminousIntensity property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateLuminousIntensityProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsLuminousIntensityMeasure); + } + + /// + /// Create Mass property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateMassProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsMassMeasure); + } + + /// + /// Create MassDensity property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateMassDensityProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsMassDensityMeasure); + } + + /// + /// Create MassFlowRate property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateMassFlowRateProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsMassFlowRateMeasure); + } + + /// + /// Create MassPerLength property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateMassPerLengthProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsMassPerLengthMeasure); + } + + /// + /// Create ModulusOfElasticity property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateModulusOfElasticityProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsModulusOfElasticityMeasure); + } + + /// + /// Create MoistureDiffusivity property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateMoistureDiffusivityProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsMoistureDiffusivityMeasure); + } + + /// + /// Create MomentOfInertia property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateMomentOfInertiaProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsMomentOfInertiaMeasure); + } + + /// + /// Create NormalisedRatio property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateNormalisedRatioProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsNormalisedRatioMeasure); + } + + /// + /// Create Numeric property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateNumericProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsNumeric); + } + + /// + /// Create PlaneAngle property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreatePlaneAngleProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsPlaneAngleMeasure); + } + + /// + /// Create PlanarForce property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreatePlanarForceProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsPlanarForceMeasure); + } - return propertyHandle; + /// + /// Create PositiveLength property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreatePositiveLengthProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsPositiveLengthMeasure); } /// - /// Creates and associates the common property sets associated with ElementTypes. These are handled differently than for elements. + /// Create PositiveRatio property. /// - /// The IFC exporter object. - /// The element type whose properties are exported. - /// The handles of property sets already associated with the type. - /// The handle of the entity associated with the element type object. - public static void CreateElementTypeProperties(ExporterIFC exporterIFC, ElementType elementType, - HashSet existingPropertySets, IFCAnyHandle prodTypeHnd) + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreatePositiveRatioProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) { - HashSet propertySets = new HashSet(); + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsPositiveRatioMeasure); + } - // Pass in an empty set of handles - we don't want IfcRelDefinesByProperties for type properties. - ISet associatedObjectIds = new HashSet(); - CreateInternalRevitPropertySets(exporterIFC, elementType, associatedObjectIds, false); + /// + /// Create PositivePlaneAngle property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreatePositivePlaneAngleProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsPositivePlaneAngleMeasure); + } - TypePropertyInfo additionalPropertySets = null; - ElementId typeId = elementType.Id; - if (ExporterCacheManager.TypePropertyInfoCache.TryGetValue(typeId, out additionalPropertySets)) - propertySets.UnionWith(additionalPropertySets.PropertySets); + /// + /// Create Power property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreatePowerProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsPowerMeasure); + } - if (existingPropertySets != null && existingPropertySets.Count > 0) - propertySets.UnionWith(existingPropertySets); + /// + /// Create Pressure property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreatePressureProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsPressureMeasure); + } - IFCFile file = exporterIFC.GetFile(); - using (IFCTransaction transaction = new IFCTransaction(file)) - { - Document doc = elementType.Document; + /// + /// Create Ratio property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateRatioProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsRatioMeasure); + } - IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; + /// + /// Create Real property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateRealProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsReal); + } - IList currPsetsToCreate = - ExporterUtil.GetCurrPSetsToCreate(prodTypeHnd, PSetsToProcess.Type); - foreach (PropertySetDescription currDesc in currPsetsToCreate) - { - // Last conditional check: if the property set comes from a ViewSchedule, check if the element is in the schedule. - if (currDesc.ViewScheduleId != ElementId.InvalidElementId) - if (!ExporterCacheManager.ViewScheduleElementCache[currDesc.ViewScheduleId].Contains(typeId)) - continue; + /// + /// Create RotationalFrequency property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateRotationalFrequencyProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsRotationalFrequencyMeasure); + } - ElementOrConnector elementOrConnector = new ElementOrConnector(elementType); - ISet props = currDesc.ProcessEntries(file, exporterIFC, null, elementOrConnector, elementType, prodTypeHnd); - if (props.Count > 0) - { - string paramSetName = currDesc.Name; - string guid = GUIDUtil.GenerateIFCGuidFrom( - GUIDUtil.CreateGUIDString(IFCEntityType.IfcPropertySet, paramSetName, prodTypeHnd)); + /// + /// Create SoundPower property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateSoundPowerProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsSoundPowerMeasure); + } - IFCAnyHandle propertySet = IFCInstanceExporter.CreatePropertySet(file, guid, ownerHistory, paramSetName, null, props); - propertySets.Add(propertySet); - } - } + /// + /// Create SoundPressure property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateSoundPressureProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsSoundPressureMeasure); + } - if (propertySets.Count != 0) - { - prodTypeHnd.SetAttribute("HasPropertySets", propertySets); - // Don't assign the property sets to the instances if we have just assigned them to the type. - if (additionalPropertySets != null) - additionalPropertySets.AssignedToType = true; - } + /// + /// Create SpecificHeatCapacity property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateSpecificHeatCapacityProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsSpecificHeatCapacityMeasure); + } - transaction.Commit(); - } + /// + /// Create ThermalConductivity property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateThermalConductivityProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsThermalConductivityMeasure); + } + + /// + /// Create ThermalExpansionCoefficient property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateThermalExpansionCoefficientProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsThermalExpansionCoefficientMeasure); + } + + /// + /// Create ThermalResistance property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateThermalResistanceProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsThermalResistanceMeasure); + } + + /// + /// Create ThermalTransmittance property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateThermalTransmittanceProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsThermalTransmittanceMeasure); + } + + /// + /// Create ThermodynamicTemperature property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateThermodynamicTemperatureProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsThermodynamicTemperatureMeasure); + } + + /// + /// Create VaporPermeability property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateVaporPermeabilityProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsVaporPermeabilityMeasure); + } + + /// + /// Create Volume property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateVolumeProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsVolumeMeasure); + } + + /// + /// Create VolumetricFlowRate property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateVolumetricFlowRateProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsVolumetricFlowRateMeasure); + } + + /// + /// Create Torque property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateTorqueProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsTorqueMeasure); + } + + /// + /// Create WarpingConstant property. + /// + /// The IFC file. + /// The name of the property. + /// The values of the property. + /// The value type of the property. + /// The created property handle. + public static IFCAnyHandle CreateWarpingConstantProperty(IFCFile file, string propertyName, IList values, PropertyValueType valueType, string unitTypeKey) + { + return CreateGenericProperty(file, propertyName, values, valueType, unitTypeKey, IFCDataUtil.CreateAsWarpingConstantMeasure); } + #endregion + } } \ No newline at end of file diff --git a/Source/Revit.IFC.Export/Exporter/ProxyElementExporter.cs b/Source/Revit.IFC.Export/Exporter/ProxyElementExporter.cs index f2fec6ff..bf64d725 100644 --- a/Source/Revit.IFC.Export/Exporter/ProxyElementExporter.cs +++ b/Source/Revit.IFC.Export/Exporter/ProxyElementExporter.cs @@ -49,7 +49,7 @@ class ProxyElementExporter if (exportType == null) { - exportType = new IFCExportInfoPair(IFCEntityType.IfcBuildingElementProxy, IFCEntityType.IfcBuildingElementProxyType, "NOTDEFINED"); + exportType = new IFCExportInfoPair(IFCEntityType.IfcBuildingElementProxy, IFCEntityType.IfcBuildingElementProxyType, null); } IFCFile file = exporterIFC.GetFile(); diff --git a/Source/Revit.IFC.Export/Exporter/RailingExporter.cs b/Source/Revit.IFC.Export/Exporter/RailingExporter.cs index b8adcc09..db74023a 100644 --- a/Source/Revit.IFC.Export/Exporter/RailingExporter.cs +++ b/Source/Revit.IFC.Export/Exporter/RailingExporter.cs @@ -144,7 +144,7 @@ public static void ExportRailingElement(ExporterIFC exporterIFC, Railing railing IFCExportInfoPair exportType = ExporterUtil.GetProductExportType(exporterIFC, railing, out ifcEnumType); if (exportType.IsUnKnown) { - ifcEnumType = ExporterUtil.GetIFCTypeFromExportTable(exporterIFC, railing); + ifcEnumType = ExporterUtil.GetIFCTypeFromExportTable(railing); } ExportRailing(exporterIFC, railing, geomElement, ifcEnumType, productWrapper); diff --git a/Source/Revit.IFC.Export/Exporter/RampExporter.cs b/Source/Revit.IFC.Export/Exporter/RampExporter.cs index 182f0940..05c708e4 100644 --- a/Source/Revit.IFC.Export/Exporter/RampExporter.cs +++ b/Source/Revit.IFC.Export/Exporter/RampExporter.cs @@ -369,9 +369,9 @@ public static string GetIFCRampType(string rampTypeName) string predefType = ifcEnumType; IFCExportInfoPair exportTypePair = ExporterUtil.GetProductExportType(exporterIFC, ramp, out ifcEnumType); - if (!string.IsNullOrEmpty(exportTypePair.ValidatedPredefinedType)) + if (!exportTypePair.IsPredefinedTypeDefault) { - predefType = exportTypePair.ValidatedPredefinedType; + predefType = exportTypePair.PredefinedType; } SortedDictionary> rampFlights = null; @@ -579,7 +579,7 @@ public static string GetIFCRampType(string rampTypeName) IFCAnyHandle localPlacement = ecData.GetLocalPlacement(); IFCAnyHandle rampHnd = IFCInstanceExporter.CreateRamp(exporterIFC, ramp, guid, ownerHistory, - localPlacement, representation, exportTypePair.ValidatedPredefinedType); + localPlacement, representation, exportTypePair.GetPredefinedTypeOrDefault()); productWrapper.AddElement(ramp, rampHnd, placementSetter.LevelInfo, ecData, true, exportTypePair); CategoryUtil.CreateMaterialAssociation(exporterIFC, rampHnd, bodyData.MaterialIds); @@ -593,7 +593,7 @@ public static string GetIFCRampType(string rampTypeName) List components = new List(); IList componentExtrusionData = new List(); IFCAnyHandle containedRampHnd = IFCInstanceExporter.CreateRamp(exporterIFC, ramp, containedRampGuid, ownerHistory, - containedRampLocalPlacement, representation, exportTypePair.ValidatedPredefinedType); + containedRampLocalPlacement, representation, exportTypePair.GetPredefinedTypeOrDefault()); components.Add(containedRampHnd); componentExtrusionData.Add(ecData); //productWrapper.AddElement(containedRampHnd, placementSetter.LevelInfo, ecData, false); @@ -603,7 +603,7 @@ public static string GetIFCRampType(string rampTypeName) IFCAnyHandle localPlacement = ecData.GetLocalPlacement(); IFCAnyHandle rampHnd = IFCInstanceExporter.CreateRamp(exporterIFC, ramp, guid, ownerHistory, - localPlacement, null, exportTypePair.ValidatedPredefinedType); + localPlacement, null, exportTypePair.GetPredefinedTypeOrDefault()); productWrapper.AddElement(ramp, rampHnd, placementSetter.LevelInfo, ecData, true, exportTypePair); string typeGuid = GUIDUtil.CreateGUID(rampType); @@ -633,19 +633,19 @@ public static string GetIFCRampType(string rampTypeName) /// The ProductWrapper. public static void Export(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, ProductWrapper productWrapper) { - string ifcEnumType = ExporterUtil.GetIFCTypeFromExportTable(exporterIFC, element); + IFCExportInfoPair exportType = ExporterUtil.GetProductExportType(exporterIFC, element, out _); IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { - StairsExporter.ExportLegacyStairOrRampAsContainer(exporterIFC, ifcEnumType, element, geometryElement, productWrapper); + StairsExporter.ExportLegacyStairOrRampAsContainer(exporterIFC, exportType.GetPredefinedTypeOrDefault(), element, geometryElement, productWrapper); // If we didn't create a handle here, then the element wasn't a "native" Ramp, and is likely a FamilyInstance or a DirectShape. if (IFCAnyHandleUtil.IsNullOrHasNoValue(productWrapper.GetAnElement())) { int numFlights = GetNumFlightsForRamp(exporterIFC, element); if (numFlights > 0) - ExportRamp(exporterIFC, ifcEnumType, element, geometryElement, numFlights, productWrapper); + ExportRamp(exporterIFC, exportType.PredefinedType, element, geometryElement, numFlights, productWrapper); } tr.Commit(); diff --git a/Source/Revit.IFC.Export/Exporter/RebarCouplerExporter.cs b/Source/Revit.IFC.Export/Exporter/RebarCouplerExporter.cs index ba853da7..ba410d4b 100644 --- a/Source/Revit.IFC.Export/Exporter/RebarCouplerExporter.cs +++ b/Source/Revit.IFC.Export/Exporter/RebarCouplerExporter.cs @@ -28,6 +28,7 @@ using Revit.IFC.Export.Exporter.PropertySet; using Revit.IFC.Common.Utility; using Revit.IFC.Common.Enums; +using System.Reflection; namespace Revit.IFC.Export.Exporter @@ -53,22 +54,22 @@ public static void ExportCoupler(ExporterIFC exporterIFC, RebarCoupler coupler, if (familySymbol == null) return; + string ifcEnumType; + IFCExportInfoPair exportType = ExporterUtil.GetProductExportType(exporterIFC, coupler, out ifcEnumType); + // Check the intended IFC entity or type name is in the exclude list specified in the UI - IFCEntityType elementClassTypeEnum = IFCEntityType.IfcMechanicalFastener; - if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) + if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(exportType.ExportInstance)) return; ElementId categoryId = CategoryUtil.GetSafeCategoryId(coupler); IFCFile file = exporterIFC.GetFile(); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; - Options options = GeometryUtil.GetIFCExportGeometryOptions(); ; - string ifcEnumType; - IFCExportInfoPair exportType = ExporterUtil.GetProductExportType(exporterIFC, coupler, out ifcEnumType); + Options options = GeometryUtil.GetIFCExportGeometryOptions(); using (IFCTransaction tr = new IFCTransaction(file)) { - var typeKey = new TypeObjectKey(typeId, ElementId.InvalidElementId, false, exportType, ElementId.InvalidElementId); + TypeObjectKey typeKey = new TypeObjectKey(typeId, ElementId.InvalidElementId, false, exportType, ElementId.InvalidElementId); FamilyTypeInfo currentTypeInfo = ExporterCacheManager.FamilySymbolToTypeInfoCache.Find(typeKey); @@ -90,8 +91,7 @@ public static void ExportCoupler(ExporterIFC exporterIFC, RebarCoupler coupler, repMap.Add(IFCInstanceExporter.CreateRepresentationMap(file, origin, bodyData.RepresentationHnd)); string typeGuid = GUIDUtil.GenerateIFCGuidFrom(familySymbol, exportType); - IFCAnyHandle styleHandle = FamilyExporterUtil.ExportGenericType(exporterIFC, exportType, - ifcEnumType, propertySetsOpt, repMap, coupler, familySymbol, typeGuid); + IFCAnyHandle styleHandle = FamilyExporterUtil.ExportGenericType(exporterIFC, exportType, propertySetsOpt, repMap, coupler, familySymbol, typeGuid); productWrapper.RegisterHandleWithElementType(familySymbol, exportType, styleHandle, propertySetsOpt); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(styleHandle)) @@ -108,6 +108,8 @@ public static void ExportCoupler(ExporterIFC exporterIFC, RebarCoupler coupler, ISet createdRebarCouplerHandles = new HashSet(); string origInstanceName = NamingUtil.GetNameOverride(coupler, NamingUtil.GetIFCName(coupler)); + bool hasTypeInfo = !IFCAnyHandleUtil.IsNullOrHasNoValue(currentTypeInfo.Style); + for (int idx = 0; idx < nCouplerQuantity; idx++) { string instanceGUID = GUIDUtil.GenerateIFCGuidFrom( @@ -158,6 +160,11 @@ public static void ExportCoupler(ExporterIFC exporterIFC, RebarCoupler coupler, createdRebarCouplerHandles.Add(instanceHandle); productWrapper.AddElement(coupler, instanceHandle, setter, null, true, exportType); + + if (hasTypeInfo) + { + ExporterCacheManager.TypeRelationsCache.Add(currentTypeInfo.Style, instanceHandle); + } } } diff --git a/Source/Revit.IFC.Export/Exporter/RebarExporter.cs b/Source/Revit.IFC.Export/Exporter/RebarExporter.cs index cc805b1a..69df5f05 100644 --- a/Source/Revit.IFC.Export/Exporter/RebarExporter.cs +++ b/Source/Revit.IFC.Export/Exporter/RebarExporter.cs @@ -313,7 +313,7 @@ private static IFCReinforcingBarRole GetReinforcingBarRole(string role) IFCAnyHandle localPlacement = ecData.GetLocalPlacement(); buildingElementProxy = IFCInstanceExporter.CreateBuildingElementProxy(exporterIFC, element, guid, - ownerHistory, localPlacement, representation, exportType.ValidatedPredefinedType); + ownerHistory, localPlacement, representation, exportType.GetPredefinedTypeOrDefault()); productWrapper.AddElement(element, buildingElementProxy, placementSetter.LevelInfo, ecData, true, exportType); } @@ -483,7 +483,7 @@ private static ISet ExportRebar(ExporterIFC exporterIFC, continue; Rebar rebar = rebarElement as Rebar; - if ((rebar != null) && (rebar.DistributionType == DistributionType.VaryingLength || rebar.IsRebarFreeForm())) + if (rebar != null && rebar.CanHaveVaryingLengthBars) { baseCurves = GetRebarCenterlineCurves(rebar, true, false, false, MultiplanarOption.IncludeAllMultiplanarCurves, ii); DoubleParameterValue barLengthParamVal = rebar.GetParameterValueAtIndex(barLengthParamId, ii) as DoubleParameterValue; @@ -841,7 +841,7 @@ static void CacheSubelementParameterValues(Element element, ParameterSet paramet if (element is Rebar) { Rebar rebar = element as Rebar; - if (rebar.DistributionType != DistributionType.VaryingLength && !rebar.IsRebarFreeForm()) + if (!rebar.CanHaveVaryingLengthBars) return; foreach (Parameter param in parameters) diff --git a/Source/Revit.IFC.Export/Exporter/RoofExporter.cs b/Source/Revit.IFC.Export/Exporter/RoofExporter.cs index e6709f15..10800495 100644 --- a/Source/Revit.IFC.Export/Exporter/RoofExporter.cs +++ b/Source/Revit.IFC.Export/Exporter/RoofExporter.cs @@ -26,6 +26,7 @@ using Revit.IFC.Common.Utility; using Revit.IFC.Common.Enums; using System.Linq; +using Revit.IFC.Export.Exporter.PropertySet; namespace Revit.IFC.Export.Exporter { @@ -43,12 +44,16 @@ class RoofExporter /// The roof element. /// The geometry element. /// The ProductWrapper. - /// Export roof as single geometry. - public static void ExportRoof(ExporterIFC exporterIFC, Element roof, ref GeometryElement geometryElement, - ProductWrapper productWrapper, bool exportRoofAsSingleGeometry = false) + public static IFCAnyHandle ExportRoof(ExporterIFC exporterIFC, Element roof, ref GeometryElement geometryElement, + ProductWrapper productWrapper) { if (roof == null || geometryElement == null) - return; + return null; + + bool exportRoofAsSingleGeometry = ExporterCacheManager.ExportOptionsCache.ExportHostAsSingleEntity || + (productWrapper != null && + !ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4 && + IFCAnyHandleUtil.IsNullOrHasNoValue(productWrapper.GetAnElement())); string ifcEnumType; IFCExportInfoPair roofExportType = ExporterUtil.GetProductExportType(exporterIFC, roof, out ifcEnumType); @@ -61,6 +66,7 @@ class RoofExporter IFCFile file = exporterIFC.GetFile(); Document doc = roof.Document; + IFCAnyHandle roofHnd = null; using (SubTransaction tempPartTransaction = new SubTransaction(doc)) { // For IFC4RV export, Roof will be split into its parts(temporarily) in order to export the roof by its parts @@ -69,7 +75,8 @@ class RoofExporter ExporterUtil.CreateParts(roof, layersetInfo.MaterialIds.Count, ref geometryElement); } - bool exportByComponents = ExporterUtil.CanExportByComponentsOrParts(roof) == ExporterUtil.ExportPartAs.ShapeAspect; + bool exportByComponents = + ExporterUtil.CanExportByComponentsOrParts(roof, ref geometryElement) == ExporterUtil.ExportPartAs.ShapeAspect; using (IFCTransaction tr = new IFCTransaction(file)) { @@ -102,16 +109,11 @@ class RoofExporter categoryId, geometryElement, bodyExporterOptions, null, ecData, out bodyData, instanceGeometry: true); if (bodyData != null && bodyData.MaterialIds != null) materialIds = bodyData.MaterialIds; - } - else - { - prodRep = RepresentationUtil.CreateProductDefinitionShapeWithoutBodyRep(exporterIFC, roof, categoryId, geometryElement, representations); - } - - if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodRep)) - { - ecData.ClearOpenings(); - return; + if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodRep)) + { + ecData.ClearOpenings(); + return null; + } } bool exportSlab = ((ecData.ScaledLength > MathUtil.Eps() || exportByComponents) && @@ -121,9 +123,23 @@ class RoofExporter IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; IFCAnyHandle localPlacement = ecData.GetLocalPlacement(); - IFCAnyHandle roofHnd = IFCInstanceExporter.CreateGenericIFCEntity( - roofExportType, exporterIFC, roof, guid, ownerHistory, - localPlacement, exportSlab ? null : prodRep); + if (exportByComponents) + { + if (exportSlab || exportRoofAsSingleGeometry) + { + prodRep = RepresentationUtil.CreateProductDefinitionShapeWithoutBodyRep(exporterIFC, roof, categoryId, geometryElement, representations); + IFCAnyHandle hostShapeRepFromParts = PartExporter.ExportHostPartAsShapeAspects(exporterIFC, roof, prodRep, + productWrapper, placementSetter, localPlacement, ElementId.InvalidElementId, layersetInfo, ecData); + } + else + { + ecData.ClearOpenings(); + return null; + } + } + + roofHnd = IFCInstanceExporter.CreateGenericIFCEntity(roofExportType, exporterIFC, roof, guid, + ownerHistory, localPlacement, exportSlab ? null : prodRep); IFCAnyHandle typeHnd = ExporterUtil.CreateGenericTypeFromElement(roof, roofExportType, file, productWrapper); @@ -134,12 +150,6 @@ class RoofExporter if (!(roof is RoofBase)) CategoryUtil.CreateMaterialAssociation(exporterIFC, roofHnd, materialIds); - if (exportByComponents && (exportSlab || exportRoofAsSingleGeometry)) - { - IFCAnyHandle hostShapeRepFromParts = PartExporter.ExportHostPartAsShapeAspects(exporterIFC, roof, prodRep, - productWrapper, placementSetter, localPlacement, ElementId.InvalidElementId, layersetInfo, ecData); - } - Transform offsetTransform = (bodyData != null) ? bodyData.OffsetTransform : Transform.Identity; if (exportSlab) @@ -194,7 +204,7 @@ class RoofExporter } else if (layersetInfo != null && layersetInfo.MaterialIds != null) { - materialIds = layersetInfo.MaterialIds.Select(x => x.m_baseMatId).ToList(); + materialIds = layersetInfo.MaterialIds.Select(x => x.BaseMatId).ToList(); CategoryUtil.CreateMaterialAssociation(exporterIFC, roofHnd, materialIds); } } @@ -204,6 +214,8 @@ class RoofExporter } } } + + return roofHnd; } /// @@ -222,11 +234,6 @@ public static void Export(ExporterIFC exporterIFC, RoofBase roof, ref GeometryEl bool exportParts = PartExporter.CanExportParts(roof); bool exportAsCurtainRoof = CurtainSystemExporter.IsCurtainSystem(roof); - // if there is only a single part that we can get from the roof geometry, we will not create the aggregation with IfcSlab, but directly export the IfcRoof - bool exportAsSingleGeometry = false; - if (productWrapper != null && !ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4) - exportAsSingleGeometry = IFCAnyHandleUtil.IsNullOrHasNoValue(productWrapper.GetAnElement()); - if (exportParts) { if (!PartExporter.CanExportElementInPartExport(roof, roof.LevelId, false)) @@ -239,26 +246,26 @@ public static void Export(ExporterIFC exporterIFC, RoofBase roof, ref GeometryEl } else { - string ifcEnumType; - IFCExportInfoPair roofExportType = ExporterUtil.GetProductExportType(exporterIFC, roof, out ifcEnumType); + IFCExportInfoPair roofExportType = ExporterUtil.GetProductExportType(exporterIFC, roof, out _); + IFCAnyHandle roofHnd = null; if (roofExportType.ExportInstance != IFCEntityType.IfcRoof) { - ExportRoof(exporterIFC, roof, ref geometryElement, productWrapper, exportAsSingleGeometry); + roofHnd = ExportRoof(exporterIFC, roof, ref geometryElement, productWrapper); } else { - IFCAnyHandle roofHnd = ExportRoofOrFloorAsContainer(exporterIFC, roof, + roofHnd = ExportRoofOrFloorAsContainer(exporterIFC, roof, geometryElement, productWrapper); if (IFCAnyHandleUtil.IsNullOrHasNoValue(roofHnd)) { - ExportRoof(exporterIFC, roof, ref geometryElement, productWrapper, exportAsSingleGeometry); + roofHnd = ExportRoof(exporterIFC, roof, ref geometryElement, productWrapper); } } // call for host objects; curtain roofs excused from call (no material information) if (!ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView) - HostObjectExporter.ExportHostObjectMaterials(exporterIFC, roof, productWrapper.GetAnElement(), + HostObjectExporter.ExportHostObjectMaterials(exporterIFC, roof, roofHnd, geometryElement, productWrapper, ElementId.InvalidElementId, IFCLayerSetDirection.Axis3, null, null); } tr.Commit(); @@ -266,14 +273,16 @@ public static void Export(ExporterIFC exporterIFC, RoofBase roof, ref GeometryEl } /// - /// Exports a roof or floor as a container of multiple roof slabs. Returns the handle, if successful. + /// Exports a roof or floor as a container of multiple roof slabs. Returns the handle, + /// if successful. /// /// The exporter. /// The roof or floor element. /// The geometry of the element. /// The product wrapper. /// The roof handle. - /// For floors, if there is only one component, return null, as we do not want to create a container. + /// For floors, if there is only one component, return null, as we do not want to + /// create a container. public static IFCAnyHandle ExportRoofOrFloorAsContainer(ExporterIFC exporterIFC, Element element, GeometryElement geometry, ProductWrapper productWrapper) { @@ -285,8 +294,7 @@ public static void Export(ExporterIFC exporterIFC, RoofBase roof, ref GeometryEl if (!elementIsRoof && !elementIsFloor) return null; - IFCExportInfoPair roofExportType = ExporterUtil.GetProductExportType(exporterIFC, element, - out _); + IFCExportInfoPair roofExportType = ExporterUtil.GetProductExportType(exporterIFC, element, out _); if (roofExportType.IsUnKnown) { IFCEntityType elementClassTypeEnum = @@ -303,18 +311,14 @@ public static void Export(ExporterIFC exporterIFC, RoofBase roof, ref GeometryEl { using (IFCTransaction transaction = new IFCTransaction(file)) { - MaterialLayerSetInfo layersetInfo = new MaterialLayerSetInfo(exporterIFC, element, - productWrapper); - bool hasLayers = false; - if (layersetInfo.MaterialIds.Count > 1) - hasLayers = true; - bool exportByComponents = - ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView && hasLayers; + MaterialLayerSetInfo layersetInfo = new MaterialLayerSetInfo(exporterIFC, element, productWrapper); + bool hasLayers = (layersetInfo.MaterialIds.Count > 1); + bool exportByComponents = ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView && hasLayers; // Check for containment override IFCAnyHandle overrideContainerHnd = null; - ElementId overrideContainerId = ParameterUtil.OverrideContainmentParameter(exporterIFC, - element, out overrideContainerHnd); + ElementId overrideContainerId = ParameterUtil.OverrideContainmentParameter(exporterIFC, element, + out overrideContainerHnd); // We want to delay creating entity handles until as late as possible, so that if we // abort the IFC transaction, we don't have to delete elements. This is both for @@ -323,21 +327,27 @@ public static void Export(ExporterIFC exporterIFC, RoofBase roof, ref GeometryEl IList hostObjectSubcomponents = null; try { - hostObjectSubcomponents = - ExporterIFCUtils.ComputeSubcomponents(element as HostObject); + hostObjectSubcomponents = ExporterIFCUtils.ComputeSubcomponents(element as HostObject); + if (hostObjectSubcomponents == null) + return null; } catch { return null; } - if (hostObjectSubcomponents == null) - return null; + bool createSubcomponents = !ExporterCacheManager.ExportOptionsCache.ExportHostAsSingleEntity; int numSubcomponents = hostObjectSubcomponents.Count; if (numSubcomponents == 0 || (elementIsFloor && numSubcomponents == 1)) + { return null; + } + // TODO: If we find exactly 1 sub-component and we are exporting a floor, then we will + // continue, but with createSubcomponents set to false. + // if (createSubcomponents && elementIsFloor && numSubcomponents == 1) createSubcomponents = false; + using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element, null, null, overrideContainerId, overrideContainerHnd)) { IFCAnyHandle localPlacement = setter.LocalPlacement; @@ -353,27 +363,12 @@ public static void Export(ExporterIFC exporterIFC, RoofBase roof, ref GeometryEl using (TransformSetter trfSetter = TransformSetter.Create()) { - IList geometryList = new List(); - geometryList.Add(geometry); + IList geometryList = new List() { geometry }; trfSetter.InitializeFromBoundingBox(exporterIFC, geometryList, extrusionCreationData); - IFCAnyHandle prodRepHnd = null; - - string elementGUID = GUIDUtil.CreateGUID(element); - - hostObjectHandle = IFCInstanceExporter.CreateGenericIFCEntity( - roofExportType, exporterIFC, element, elementGUID, ownerHistory, - localPlacement, prodRepHnd); - - if (IFCAnyHandleUtil.IsNullOrHasNoValue(hostObjectHandle)) - return null; - - IList elementHandles = new List(); - elementHandles.Add(hostObjectHandle); - // If element is floor, then the profile curve loop of hostObjectSubComponent is computed from the top face of the floor // else if element is roof, then the profile curve loop is taken from the bottom face of the roof instead - XYZ extrusionDir = elementIsFloor ? new XYZ(0, 0, -1) : new XYZ(0, 0, 1); + XYZ extrusionDir = elementIsFloor ? -XYZ.BasisZ : XYZ.BasisZ; ElementId catId = CategoryUtil.GetSafeCategoryId(element); @@ -382,103 +377,134 @@ public static void Export(ExporterIFC exporterIFC, RoofBase roof, ref GeometryEl IList hostObjectOpeningLoops = new List(); double maximumScaledDepth = 0.0; - using (IFCExportBodyParams slabExtrusionCreationData = new IFCExportBodyParams()) + int loopNum = 0; + int subElementStart = elementIsRoof ? (int)IFCRoofSubElements.RoofSlabStart : (int)IFCSlabSubElements.SubSlabStart; + + // Figure out the appropriate slabExportType from the main handle. + IFCExportInfoPair subInfoPair; + switch (roofExportType.ExportInstance) { - slabExtrusionCreationData.SetLocalPlacement(extrusionCreationData.GetLocalPlacement()); - slabExtrusionCreationData.ReuseLocalPlacement = false; - slabExtrusionCreationData.ForceOffset = true; + case IFCEntityType.IfcRoof: + subInfoPair = new IFCExportInfoPair(IFCEntityType.IfcSlab, "Roof"); + break; + case IFCEntityType.IfcSlab: + subInfoPair = roofExportType; + break; + default: + subInfoPair = new IFCExportInfoPair(IFCEntityType.IfcBuildingElementPart); + break; + } - int loopNum = 0; - int subElementStart = elementIsRoof ? (int)IFCRoofSubElements.RoofSlabStart : (int)IFCSlabSubElements.SubSlabStart; + List hostBodyItems = new List(); + IFCAnyHandle contextOfItems = ExporterCacheManager.Get3DContextHandle(IFCRepresentationIdentifier.Body); + IList elementHandles = new List(); - // Figure out the appropriate slabExportType from the main handle. - IFCExportInfoPair subInfoPair; - switch (roofExportType.ExportInstance) + foreach (HostObjectSubcomponentInfo hostObjectSubcomponent in hostObjectSubcomponents) + { + IFCExportBodyParams slabExtrusionCreationData = null; + + if (createSubcomponents) { - case IFCEntityType.IfcRoof: - subInfoPair = new IFCExportInfoPair(IFCEntityType.IfcSlab, "Roof"); - break; - case IFCEntityType.IfcSlab: - subInfoPair = roofExportType; - break; - default: - subInfoPair = new IFCExportInfoPair(IFCEntityType.IfcBuildingElementPart); - break; + slabExtrusionCreationData = new IFCExportBodyParams(); + + slabExtrusionCreationData.SetLocalPlacement(extrusionCreationData.GetLocalPlacement()); + slabExtrusionCreationData.ReuseLocalPlacement = false; + slabExtrusionCreationData.ForceOffset = true; + + trfSetter.InitializeFromBoundingBox(exporterIFC, geometryList, slabExtrusionCreationData); } - foreach (HostObjectSubcomponentInfo hostObjectSubcomponent in hostObjectSubcomponents) + Plane plane = hostObjectSubcomponent.GetPlane(); + Transform lcs = GeometryUtil.CreateTransformFromPlane(plane); + + IList curveLoops = new List(); + CurveLoop slabCurveLoop = hostObjectSubcomponent.GetCurveLoop(); + curveLoops.Add(slabCurveLoop); + + double slope = Math.Abs(plane.Normal.Z); + double scaledDepth = UnitUtil.ScaleLength(hostObjectSubcomponent.Depth); + double scaledExtrusionDepth = scaledDepth * slope; + IList matLayerNames = new List(); + + // Create representation items based on the layers + // Because in this case, the Roof components are not derived from Parts, but by "splitting" geometry part that can be extruded, + // the creation of the Items for IFC4RV will be different by using "manual" split based on the layer thickness + IList bodyItems = new List(); + if (!exportByComponents) { - trfSetter.InitializeFromBoundingBox(exporterIFC, geometryList, slabExtrusionCreationData); - Plane plane = hostObjectSubcomponent.GetPlane(); - Transform lcs = GeometryUtil.CreateTransformFromPlane(plane); - - IList curveLoops = new List(); - - CurveLoop slabCurveLoop = hostObjectSubcomponent.GetCurveLoop(); - curveLoops.Add(slabCurveLoop); - double slope = Math.Abs(plane.Normal.Z); - double scaledDepth = UnitUtil.ScaleLength(hostObjectSubcomponent.Depth); - double scaledExtrusionDepth = scaledDepth * slope; - IList shapeReps = new List(); - IFCAnyHandle prodDefShape = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps); - IFCAnyHandle contextOfItems = ExporterCacheManager.Get3DContextHandle(IFCRepresentationIdentifier.Body); - string representationType = ShapeRepresentationType.SweptSolid.ToString(); - - // Create representation items based on the layers - // Because in this case, the Roof components are not derived from Parts, but by "splitting" geometry part that can be extruded, - // the creation of the Items for IFC4RV will be different by using "manual" split based on the layer thickness - HashSet bodyItems = new HashSet(); - if (!exportByComponents) + IFCAnyHandle itemShapeRep = + ExtrusionExporter.CreateExtrudedSolidFromCurveLoop(exporterIFC, + null, curveLoops, lcs, extrusionDir, scaledExtrusionDepth, false, + out IList validatedCurveLoops); + if (IFCAnyHandleUtil.IsNullOrHasNoValue(itemShapeRep)) + { + productWrapper.ClearInternalHandleWrapperData(element); + if ((validatedCurveLoops?.Count ?? 0) == 0) continue; + + return null; + } + ElementId matId = HostObjectExporter.GetFirstLayerMaterialId(element as HostObject); + BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, + element.Document, false, itemShapeRep, matId); + bodyItems.Add(itemShapeRep); + } + else + { + List MaterialIds = layersetInfo.MaterialIds; + ElementId typeElemId = element.GetTypeId(); + // From CollectMaterialLayerSet() Roofs with no components are only allowed one material. It arbitrarily chooses the thickest material. + // To be consistant with Roof(as Slab), we will reverse the order. + IFCAnyHandle materialLayerSet = ExporterCacheManager.MaterialSetCache.FindLayerSet(typeElemId); + bool materialHandleIsNotValid = IFCAnyHandleUtil.IsNullOrHasNoValue(materialLayerSet); + if (IFCAnyHandleUtil.IsNullOrHasNoValue(materialLayerSet) || materialHandleIsNotValid) + MaterialIds.Reverse(); + + double scaleProj = extrusionDir.DotProduct(plane.Normal); + foreach (MaterialLayerSetInfo.MaterialInfo matLayerInfo in MaterialIds) { - IFCAnyHandle itemShapeRep = ExtrusionExporter.CreateExtrudedSolidFromCurveLoop(exporterIFC, null, curveLoops, lcs, extrusionDir, scaledExtrusionDepth, false, out IList validatedCurveLoops); + double itemExtrDepth = matLayerInfo.Width; + double scaledItemExtrDepth = UnitUtil.ScaleLength(itemExtrDepth) * slope; + IFCAnyHandle itemShapeRep = ExtrusionExporter.CreateExtrudedSolidFromCurveLoop(exporterIFC, null, curveLoops, lcs, extrusionDir, scaledItemExtrDepth, false, out _); if (IFCAnyHandleUtil.IsNullOrHasNoValue(itemShapeRep)) { productWrapper.ClearInternalHandleWrapperData(element); - if ((validatedCurveLoops?.Count ?? 0) == 0) continue; - return null; } - ElementId matId = HostObjectExporter.GetFirstLayerMaterialId(element as HostObject); - BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, element.Document, false, itemShapeRep, matId); + + BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, element.Document, false, itemShapeRep, matLayerInfo.BaseMatId); + bodyItems.Add(itemShapeRep); + matLayerNames.Add(matLayerInfo.LayerName); + + XYZ offset = new XYZ(0, 0, itemExtrDepth / scaleProj); // offset is calculated as extent in the direction of extrusion + lcs.Origin += offset; } - else + } + + if (createSubcomponents) + { + IList shapeReps = new List { - List MaterialIds = layersetInfo.MaterialIds; - ElementId typeElemId = element.GetTypeId(); - // From CollectMaterialLayerSet() Roofs with no components are only allowed one material. It arbitrarily chooses the thickest material. - // To be consistant with Roof(as Slab), we will reverse the order. - IFCAnyHandle materialLayerSet = ExporterCacheManager.MaterialSetCache.FindLayerSet(typeElemId); - bool materialHandleIsNotValid = IFCAnyHandleUtil.IsNullOrHasNoValue(materialLayerSet); - if (IFCAnyHandleUtil.IsNullOrHasNoValue(materialLayerSet) || materialHandleIsNotValid) - MaterialIds.Reverse(); - - double scaleProj = extrusionDir.DotProduct(plane.Normal); - foreach (MaterialLayerSetInfo.MaterialInfo matLayerInfo in MaterialIds) + RepresentationUtil.CreateSweptSolidRep(exporterIFC, element, + catId, contextOfItems, bodyItems.ToHashSet(), null, null) + }; + + IFCAnyHandle prodDefShape = + IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, + shapeReps); + + if (exportByComponents) + { + string representationType = ShapeRepresentationType.SweptSolid.ToString(); + int count = bodyItems.Count(); + for (int ii = 0; ii < count; ii++) { - double itemExtrDepth = matLayerInfo.m_matWidth; - double scaledItemExtrDepth = UnitUtil.ScaleLength(itemExtrDepth) * slope; - IFCAnyHandle itemShapeRep = ExtrusionExporter.CreateExtrudedSolidFromCurveLoop(exporterIFC, null, curveLoops, lcs, extrusionDir, scaledItemExtrDepth, false, out _); - if (IFCAnyHandleUtil.IsNullOrHasNoValue(itemShapeRep)) - { - productWrapper.ClearInternalHandleWrapperData(element); - return null; - } - - BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, element.Document, false, itemShapeRep, matLayerInfo.m_baseMatId); - - bodyItems.Add(itemShapeRep); - RepresentationUtil.CreateRepForShapeAspect(exporterIFC, element, prodDefShape, representationType, matLayerInfo.m_layerName, itemShapeRep); - - XYZ offset = new XYZ(0, 0, itemExtrDepth / scaleProj); // offset is calculated as extent in the direction of extrusion - lcs.Origin += offset; + RepresentationUtil.CreateRepForShapeAspect(exporterIFC, element, + prodDefShape, representationType, matLayerNames[ii], + bodyItems[ii]); } } - IFCAnyHandle shapeRep = RepresentationUtil.CreateSweptSolidRep(exporterIFC, element, catId, contextOfItems, bodyItems, null, null); - shapeReps.Add(shapeRep); - IFCAnyHandleUtil.SetAttribute(prodDefShape, "Representations", shapeReps); - // We could replace the code below to just use the newer, and better, // GenerateIFCGuidFrom. The code below maintains compatibility with older // versions while generating a stable GUID for all slabs (in the unlikely @@ -499,10 +525,13 @@ public static void Export(ExporterIFC exporterIFC, RoofBase roof, ref GeometryEl slabExtrusionCreationData.ScaledOuterPerimeter = UnitUtil.ScaleLength(curveLoops[0].GetExactLength()); slabExtrusionCreationData.Slope = UnitUtil.ScaleAngle(MathUtil.SafeAcos(Math.Abs(slope))); + if (ExporterCacheManager.ExportOptionsCache.ExportBaseQuantities) + PropertyUtil.CreateSlabBaseQuantities(exporterIFC, slabHnd, slabExtrusionCreationData, curveLoops[0]); + productWrapper.AddElement(null, slabHnd, setter, slabExtrusionCreationData, false, roofExportType); // Create type - IFCAnyHandle slabRoofTypeHnd = ExporterUtil.CreateGenericTypeFromElement(element, + IFCAnyHandle slabRoofTypeHnd = ExporterUtil.CreateGenericTypeFromElement(element, roofExportType, exporterIFC.GetFile(), productWrapper); ExporterCacheManager.TypeRelationsCache.Add(slabRoofTypeHnd, slabHnd); @@ -521,8 +550,33 @@ public static void Export(ExporterIFC exporterIFC, RoofBase roof, ref GeometryEl CategoryUtil.CreateMaterialAssociation(slabHnd, layersetInfo.MaterialLayerSetHandle); } } + else + { + hostBodyItems.AddRange(bodyItems); + } + } + + IFCAnyHandle hostProdDefShape = null; + if (hostBodyItems.Count() > 0) + { + IList shapeReps = new List + { + RepresentationUtil.CreateSweptSolidRep(exporterIFC, element, + catId, contextOfItems, hostBodyItems.ToHashSet(), null, null) + }; + + hostProdDefShape = IFCInstanceExporter.CreateProductDefinitionShape( + file, null, null, shapeReps); } + string elementGUID = GUIDUtil.CreateGUID(element); + + hostObjectHandle = IFCInstanceExporter.CreateGenericIFCEntity( + roofExportType, exporterIFC, element, elementGUID, ownerHistory, + localPlacement, hostProdDefShape); + + elementHandles.Add(hostObjectHandle); + productWrapper.AddElement(element, hostObjectHandle, setter, extrusionCreationData, true, roofExportType); ExporterUtil.RelateObjects(exporterIFC, null, hostObjectHandle, slabHandles); @@ -613,38 +667,38 @@ public static string GetIFCRoofType(string roofTypeName) { string typeName = NamingUtil.RemoveSpacesAndUnderscores(roofTypeName); - if (String.Compare(typeName, "ROOFTYPEENUM", true) == 0 || - String.Compare(typeName, "ROOFTYPEENUMFREEFORM", true) == 0) + if (string.Compare(typeName, "ROOFTYPEENUM", true) == 0 || + string.Compare(typeName, "ROOFTYPEENUMFREEFORM", true) == 0) return "FREEFORM"; - if (String.Compare(typeName, "FLAT", true) == 0 || - String.Compare(typeName, "FLATROOF", true) == 0) + if (string.Compare(typeName, "FLAT", true) == 0 || + string.Compare(typeName, "FLATROOF", true) == 0) return "FLAT_ROOF"; - if (String.Compare(typeName, "SHED", true) == 0 || - String.Compare(typeName, "SHEDROOF", true) == 0) + if (string.Compare(typeName, "SHED", true) == 0 || + string.Compare(typeName, "SHEDROOF", true) == 0) return "SHED_ROOF"; - if (String.Compare(typeName, "GABLE", true) == 0 || - String.Compare(typeName, "GABLEROOF", true) == 0) + if (string.Compare(typeName, "GABLE", true) == 0 || + string.Compare(typeName, "GABLEROOF", true) == 0) return "GABLE_ROOF"; - if (String.Compare(typeName, "HIP", true) == 0 || - String.Compare(typeName, "HIPROOF", true) == 0) + if (string.Compare(typeName, "HIP", true) == 0 || + string.Compare(typeName, "HIPROOF", true) == 0) return "HIP_ROOF"; - if (String.Compare(typeName, "HIPPED_GABLE", true) == 0 || - String.Compare(typeName, "HIPPED_GABLEROOF", true) == 0) + if (string.Compare(typeName, "HIPPED_GABLE", true) == 0 || + string.Compare(typeName, "HIPPED_GABLEROOF", true) == 0) return "HIPPED_GABLE_ROOF"; - if (String.Compare(typeName, "MANSARD", true) == 0 || - String.Compare(typeName, "MANSARDROOF", true) == 0) + if (string.Compare(typeName, "MANSARD", true) == 0 || + string.Compare(typeName, "MANSARDROOF", true) == 0) return "MANSARD_ROOF"; - if (String.Compare(typeName, "BARREL", true) == 0 || - String.Compare(typeName, "BARRELROOF", true) == 0) + if (string.Compare(typeName, "BARREL", true) == 0 || + string.Compare(typeName, "BARRELROOF", true) == 0) return "BARREL_ROOF"; - if (String.Compare(typeName, "BUTTERFLY", true) == 0 || - String.Compare(typeName, "BUTTERFLYROOF", true) == 0) + if (string.Compare(typeName, "BUTTERFLY", true) == 0 || + string.Compare(typeName, "BUTTERFLYROOF", true) == 0) return "BUTTERFLY_ROOF"; - if (String.Compare(typeName, "PAVILION", true) == 0 || - String.Compare(typeName, "PAVILIONROOF", true) == 0) + if (string.Compare(typeName, "PAVILION", true) == 0 || + string.Compare(typeName, "PAVILIONROOF", true) == 0) return "PAVILION_ROOF"; - if (String.Compare(typeName, "DOME", true) == 0 || - String.Compare(typeName, "DOMEROOF", true) == 0) + if (string.Compare(typeName, "DOME", true) == 0 || + string.Compare(typeName, "DOMEROOF", true) == 0) return "DOME_ROOF"; return typeName; //return unchanged. Validation for ENUM will be done later specific to schema version diff --git a/Source/Revit.IFC.Export/Exporter/SpatialElementExporter.cs b/Source/Revit.IFC.Export/Exporter/SpatialElementExporter.cs index c433cac9..c626b1db 100644 --- a/Source/Revit.IFC.Export/Exporter/SpatialElementExporter.cs +++ b/Source/Revit.IFC.Export/Exporter/SpatialElementExporter.cs @@ -27,7 +27,7 @@ using Revit.IFC.Export.Exporter.PropertySet; using Revit.IFC.Common.Enums; using Revit.IFC.Common.Utility; - +using System.Linq; namespace Revit.IFC.Export.Exporter { @@ -88,7 +88,7 @@ public static void ExportSpatialElement(ExporterIFC exporterIFC, SpatialElement // Force the default export to IfcSpace for Spatial Element if it is set to UnKnown if (exportInfo.IsUnKnown) { - exportInfo.SetValueWithPair(IFCEntityType.IfcSpace, ifcEnumType); + exportInfo.SetByTypeAndPredefinedType(IFCEntityType.IfcSpace, ifcEnumType); } // Check the intended IFC entity or type name is in the exclude list specified in the UI @@ -101,18 +101,21 @@ public static void ExportSpatialElement(ExporterIFC exporterIFC, SpatialElement using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, spatialElement, null, null)) { SpatialElementGeometryResults spatialElemGeomResult = null; - if (!CreateIFCSpace(exporterIFC, spatialElement, productWrapper, setter, exportInfo, out spatialElemGeomResult)) + IFCAnyHandle spaceHnd = CreateIFCSpace(exporterIFC, spatialElement, + productWrapper, setter, exportInfo, out spatialElemGeomResult); + if (IFCAnyHandleUtil.IsNullOrHasNoValue(spaceHnd)) + { return; - - bool isArea = (spatialElement is Area); + } // Do not create boundary information for areas. - if (!isArea && (ExporterCacheManager.ExportOptionsCache.SpaceBoundaryLevel == 1)) + if (!(spatialElement is Area) && + (ExporterCacheManager.ExportOptionsCache.SpaceBoundaryLevel == 1)) { Document document = spatialElement.Document; ElementId levelId = spatialElement.LevelId; IFCLevelInfo levelInfo = exporterIFC.GetLevelInfo(levelId); - double baseHeightNonScaled = (levelInfo != null) ? levelInfo.Elevation : 0.0; + double baseHeightNonScaled = spatialElement.Level?.Elevation ?? 0.0; try { @@ -145,7 +148,9 @@ public static void ExportSpatialElement(ExporterIFC exporterIFC, SpatialElement if (boundingElement == null) continue; - bool isObjectExt = CategoryUtil.IsElementExternal(boundingElement); + IFCInternalOrExternal internalOrExternal = IFCInternalOrExternal.NotDefined; + if (CategoryUtil.IsElementExternal(boundingElement).HasValue) + internalOrExternal = CategoryUtil.IsElementExternal(boundingElement).Value ? IFCInternalOrExternal.External : IFCInternalOrExternal.Internal; IFCGeometryInfo info = IFCGeometryInfo.CreateSurfaceGeometryInfo(spatialElement.Document.Application.VertexTolerance); @@ -162,7 +167,7 @@ public static void ExportSpatialElement(ExporterIFC exporterIFC, SpatialElement boundingElement.Id, setter.LevelId, connectionGeometry, IFCPhysicalOrVirtual.Physical, - isObjectExt ? IFCInternalOrExternal.External : IFCInternalOrExternal.Internal); + internalOrExternal); if (!ProcessIFCSpaceBoundary(exporterIFC, spaceBoundary, file)) ExporterCacheManager.SpaceBoundaryCache.Add(spaceBoundary); @@ -204,7 +209,10 @@ public static void ExportSpatialElement(ExporterIFC exporterIFC, SpatialElement else if (boundingElement is Autodesk.Revit.DB.Architecture.Room) physOrVirt = IFCPhysicalOrVirtual.NotDefined; - bool isObjectExt = CategoryUtil.IsElementExternal(boundingElement); + IFCInternalOrExternal internalOrExternal = IFCInternalOrExternal.NotDefined; + if (CategoryUtil.IsElementExternal(boundingElement).HasValue) + internalOrExternal = CategoryUtil.IsElementExternal(boundingElement).Value ? IFCInternalOrExternal.External : IFCInternalOrExternal.Internal; + bool isObjectPhys = (physOrVirt == IFCPhysicalOrVirtual.Physical); SpaceBoundary spaceBoundary = new SpaceBoundary(null, @@ -212,8 +220,8 @@ public static void ExportSpatialElement(ExporterIFC exporterIFC, SpatialElement boundingElement.Id, setter.LevelId, !IFCAnyHandleUtil.IsNullOrHasNoValue(connectionGeometry) ? connectionGeometry : null, - physOrVirt, - isObjectExt ? IFCInternalOrExternal.External : IFCInternalOrExternal.Internal); + physOrVirt, + internalOrExternal); if (!ProcessIFCSpaceBoundary(exporterIFC, spaceBoundary, file)) ExporterCacheManager.SpaceBoundaryCache.Add(spaceBoundary); @@ -340,7 +348,7 @@ public static void ExportSpatialElement(ExporterIFC exporterIFC, SpatialElement spatialElement.Id, elemId, setter.LevelId, !IFCAnyHandleUtil.IsNullOrHasNoValue(insConnectionGeom) ? insConnectionGeom : null, physOrVirt, - isObjectExt ? IFCInternalOrExternal.External : IFCInternalOrExternal.Internal); + internalOrExternal); if (!ProcessIFCSpaceBoundary(exporterIFC, instBoundary, file)) ExporterCacheManager.SpaceBoundaryCache.Add(instBoundary); } @@ -348,9 +356,6 @@ public static void ExportSpatialElement(ExporterIFC exporterIFC, SpatialElement } } } - - CreateZoneInfos(exporterIFC, file, spatialElement, productWrapper); - CreateSpaceOccupantInfo(file, spatialElement, productWrapper); } transaction.Commit(); } @@ -363,7 +368,7 @@ public static void ExportSpatialElement(ExporterIFC exporterIFC, SpatialElement /// The ExporterIFC object. /// The Revit document. /// The set of exported spaces. This is used to try to export using the standard routine for spaces that failed. - public static ISet ExportSpatialElement2ndLevel(Revit.IFC.Export.Exporter.Exporter ifcExporter, ExporterIFC exporterIFC, Document document) + public static ISet ExportSpatialElement2ndLevel(Exporter ifcExporter, ExporterIFC exporterIFC, Document document) { ISet exportedSpaceIds = new HashSet(); @@ -403,7 +408,7 @@ public static ISet ExportSpatialElement2ndLevel(Revit.IFC.Export.Expo if (!ElementFilteringUtil.IsElementVisible(spatialElement)) continue; - if (!ElementFilteringUtil.ShouldElementBeExported(exporterIFC, spatialElement, false)) + if (!ElementFilteringUtil.ShouldElementBeExported(spatialElement, false)) continue; if (ElementFilteringUtil.IsRoomInInvalidPhase(spatialElement)) @@ -425,8 +430,12 @@ public static ISet ExportSpatialElement2ndLevel(Revit.IFC.Export.Expo { // We won't use the SpatialElementGeometryResults, as these are 1st level boundaries, not 2nd level. SpatialElementGeometryResults results = null; - if (!CreateIFCSpace(exporterIFC, spatialElement, productWrapper, setter, null, out results)) + IFCAnyHandle spaceHnd = CreateIFCSpace(exporterIFC, + spatialElement, productWrapper, setter, null, out results); + if (IFCAnyHandleUtil.IsNullOrHasNoValue(spaceHnd)) + { continue; + } exportedSpaceIds.Add(spatialElement.Id); @@ -456,8 +465,6 @@ public static ISet ExportSpatialElement2ndLevel(Revit.IFC.Export.Expo } } } - CreateZoneInfos(exporterIFC, file, spatialElement, productWrapper); - CreateSpaceOccupantInfo(file, spatialElement, productWrapper); ExporterUtil.ExportRelatedProperties(exporterIFC, spatialElement, productWrapper); } @@ -506,12 +513,14 @@ public static ISet ExportSpatialElement2ndLevel(Revit.IFC.Export.Expo else if (boundingElement is Autodesk.Revit.DB.Architecture.Room) physOrVirt = IFCPhysicalOrVirtual.NotDefined; - bool isObjectExt = CategoryUtil.IsElementExternal(boundingElement); + IFCInternalOrExternal internalOrExternal = IFCInternalOrExternal.NotDefined; + if (CategoryUtil.IsElementExternal(boundingElement).HasValue) + internalOrExternal = CategoryUtil.IsElementExternal(boundingElement).Value ? IFCInternalOrExternal.External : IFCInternalOrExternal.Internal; SpaceBoundary spaceBoundary = new SpaceBoundary(name, spatialElement.Id, boundingElement?.Id ?? ElementId.InvalidElementId, levelId, connectionGeometry, physOrVirt, - isObjectExt ? IFCInternalOrExternal.External : IFCInternalOrExternal.Internal); + internalOrExternal); if (!ProcessIFCSpaceBoundary(exporterIFC, spaceBoundary, file)) ExporterCacheManager.SpaceBoundaryCache.Add(spaceBoundary); @@ -658,13 +667,12 @@ static IFCAnyHandle CreateConnectionSurfaceGeometry(ExporterIFC exporterIFC, Ene static double GetScaledHeight(SpatialElement spatialElement, ElementId levelId, IFCLevelInfo levelInfo) { Document document = spatialElement.Document; - bool isArea = spatialElement is Area; - + ElementId topLevelId = ElementId.InvalidElementId; double topOffset = 0.0; // These values are internally set for areas, but are invalid. Ignore them and just use the level height. - if (!isArea) + if (!(spatialElement is Area)) { ParameterUtil.GetElementIdValueFromElement(spatialElement, BuiltInParameter.ROOM_UPPER_LEVEL, out topLevelId); ParameterUtil.GetDoubleValueFromElement(spatialElement, BuiltInParameter.ROOM_UPPER_OFFSET, out topOffset); @@ -815,6 +823,23 @@ static XYZ GetSpaceBoundaryOffset(PlacementSetter setter) "Space Category (BOMA)", "http://www.BOMA.org"); } + static void AddAreaToAreaScheme(Element spatialElement, IFCAnyHandle spaceHnd) + { + Element areaScheme = (spatialElement as Area)?.AreaScheme; + + if (areaScheme != null) + { + ElementId areaSchemeId = areaScheme.Id; + HashSet areas = null; + if (!ExporterCacheManager.AreaSchemeCache.TryGetValue(areaSchemeId, out areas)) + { + areas = new HashSet(); + ExporterCacheManager.AreaSchemeCache[areaSchemeId] = areas; + } + areas.Add(spaceHnd); + } + } + /// /// Creates IFC room/space/area item, not include boundaries. /// @@ -822,8 +847,8 @@ static XYZ GetSpaceBoundaryOffset(PlacementSetter setter) /// The spatial element. /// The ProductWrapper. /// The PlacementSetter. - /// True if created successfully, false otherwise. - static bool CreateIFCSpace(ExporterIFC exporterIFC, SpatialElement spatialElement, ProductWrapper productWrapper, + /// Returns the created handle, or null. + static IFCAnyHandle CreateIFCSpace(ExporterIFC exporterIFC, SpatialElement spatialElement, ProductWrapper productWrapper, PlacementSetter setter, IFCExportInfoPair exportInfo, out SpatialElementGeometryResults results) { results = null; @@ -833,7 +858,7 @@ static XYZ GetSpaceBoundaryOffset(PlacementSetter setter) // Avoid throwing for a spatial element with no location. if (spatialElement.Location == null) - return false; + return null; IList curveLoops = null; GeometryElement geomElem = null; @@ -876,7 +901,7 @@ static XYZ GetSpaceBoundaryOffset(PlacementSetter setter) double scaledRoomHeight = GetScaledHeight(spatialElement, levelId, levelInfo); if (scaledRoomHeight <= 0.0) - return false; + return null; double dArea = 0.0; // Will be calculated later. IFCFile file = exporterIFC.GetFile(); @@ -914,23 +939,23 @@ static XYZ GetSpaceBoundaryOffset(PlacementSetter setter) { curveLoops = ExporterIFCUtils.GetRoomBoundaryAsCurveLoopArray(spatialElement, options, true); if (curveLoops == null || curveLoops.Count == 0) - return false; + return null; } catch { - return false; + return null; } double bottomOffset; ParameterUtil.GetDoubleValueFromElement(spatialElement, BuiltInParameter.ROOM_LOWER_OFFSET, out bottomOffset); - double elevation = (levelInfo != null) ? levelInfo.Elevation : 0.0; + double elevation = spatialElement.Level?.Elevation ?? 0.0; XYZ orig = new XYZ(0, 0, elevation + bottomOffset); Transform lcs = Transform.CreateTranslation(orig); // room calculated as level offset. IFCAnyHandle shapeRep = ExtrusionExporter.CreateExtrudedSolidFromCurveLoop(exporterIFC, null, curveLoops, lcs, XYZ.BasisZ, scaledRoomHeight, true, out _); if (IFCAnyHandleUtil.IsNullOrHasNoValue(shapeRep)) - return false; + return null; // Spaces shouldn't have styled items. HashSet bodyItems = new HashSet() { shapeRep }; @@ -954,9 +979,11 @@ static XYZ GetSpaceBoundaryOffset(PlacementSetter setter) if (exportInfo.ExportInstance == IFCEntityType.IfcSpace) { - IFCInternalOrExternal internalOrExternal = CategoryUtil.IsElementExternal(spatialElement) ? IFCInternalOrExternal.External : IFCInternalOrExternal.Internal; - string preDefinedType = string.IsNullOrWhiteSpace(exportInfo.ValidatedPredefinedType) ? - "NOTDEFINED" : exportInfo.ValidatedPredefinedType; + IFCInternalOrExternal internalOrExternal = IFCInternalOrExternal.NotDefined; + if(CategoryUtil.IsElementExternal(spatialElement).HasValue) + internalOrExternal = CategoryUtil.IsElementExternal(spatialElement).Value ? IFCInternalOrExternal.External : IFCInternalOrExternal.Internal; + + string preDefinedType = exportInfo.GetPredefinedTypeOrDefault(); spaceHnd = IFCInstanceExporter.CreateSpace(exporterIFC, spatialElement, GUIDUtil.CreateGUID(spatialElement), ExporterCacheManager.OwnerHistoryHandle, @@ -981,21 +1008,7 @@ static XYZ GetSpaceBoundaryOffset(PlacementSetter setter) if (spaceHnd != null) { productWrapper.AddSpace(spatialElement, spaceHnd, levelInfo, extraParams, true, exportInfo); - if (spatialElementAsArea != null) - { - Element areaScheme = spatialElementAsArea.AreaScheme; - if (areaScheme != null) - { - ElementId areaSchemeId = areaScheme.Id; - HashSet areas = null; - if (!ExporterCacheManager.AreaSchemeCache.TryGetValue(areaSchemeId, out areas)) - { - areas = new HashSet(); - ExporterCacheManager.AreaSchemeCache[areaSchemeId] = areas; - } - areas.Add(spaceHnd); - } - } + AddAreaToAreaScheme(spatialElement, spaceHnd); } } @@ -1003,7 +1016,7 @@ static XYZ GetSpaceBoundaryOffset(PlacementSetter setter) ExporterCacheManager.SpaceInfoCache.SetSpaceHandle(spatialElement, spaceHnd); // Find Ceiling as a Space boundary and keep the relationship in a cache for use later - bool ret = GetCeilingSpaceBoundary(spatialElement, out results); + GetCeilingSpaceBoundary(spatialElement, out results); if (!MathUtil.IsAlmostZero(dArea)) { @@ -1026,8 +1039,8 @@ static XYZ GetSpaceBoundaryOffset(PlacementSetter setter) // Export Classifications for SpatialElement for GSA/COBIE. if (ExporterCacheManager.ExportOptionsCache.ExportAsCOBIE) CreateCOBIESpaceClassifications(file, spaceHnd, spatialElement); - - return true; + + return spaceHnd; } /// @@ -1111,21 +1124,21 @@ static private IFCAnyHandle CreateSpatialZoneEnergyAnalysisPSet(IFCFile file, El string paramValue = ""; if (ParameterUtil.GetStringValueFromElement(element, "Spatial Zone Conditioning Requirement", out paramValue) != null) { - IFCData paramVal = Revit.IFC.Export.Toolkit.IFCDataUtil.CreateAsLabel(paramValue); + IFCData paramVal = IFCDataUtil.CreateAsLabel(paramValue); IFCAnyHandle propSingleValue = IFCInstanceExporter.CreatePropertySingleValue(file, "SpatialZoneConditioningRequirement", null, paramVal, null); properties.Add(propSingleValue); } if (ParameterUtil.GetStringValueFromElement(element, "HVAC System Type", out paramValue) != null) { - IFCData paramVal = Revit.IFC.Export.Toolkit.IFCDataUtil.CreateAsLabel(paramValue); + IFCData paramVal = IFCDataUtil.CreateAsLabel(paramValue); IFCAnyHandle propSingleValue = IFCInstanceExporter.CreatePropertySingleValue(file, "HVACSystemType", null, paramVal, null); properties.Add(propSingleValue); } if (ParameterUtil.GetStringValueFromElement(element, "User Defined HVAC System Type", out paramValue) != null) { - IFCData paramVal = Revit.IFC.Export.Toolkit.IFCDataUtil.CreateAsLabel(paramValue); + IFCData paramVal = IFCDataUtil.CreateAsLabel(paramValue); IFCAnyHandle propSingleValue = IFCInstanceExporter.CreatePropertySingleValue(file, "UserDefinedHVACSystemType", null, paramVal, null); properties.Add(propSingleValue); } @@ -1133,8 +1146,8 @@ static private IFCAnyHandle CreateSpatialZoneEnergyAnalysisPSet(IFCFile file, El double infiltrationRate = 0.0; if (ParameterUtil.GetDoubleValueFromElement(element, "Infiltration Rate", out infiltrationRate) != null) { - IFCData paramVal = Revit.IFC.Export.Toolkit.IFCDataUtil.CreateAsReal(infiltrationRate); - IFCAnyHandle unitHnd = !ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView ? ExporterCacheManager.UnitsCache["ACH"] : null; + IFCData paramVal = IFCDataUtil.CreateAsReal(infiltrationRate); + IFCAnyHandle unitHnd = !ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView ? ExporterCacheManager.UnitsCache.FindUserDefinedUnit("ACH") : null; IFCAnyHandle propSingleValue = IFCInstanceExporter.CreatePropertySingleValue(file, "InfiltrationRate", null, paramVal, unitHnd); properties.Add(propSingleValue); } @@ -1142,7 +1155,7 @@ static private IFCAnyHandle CreateSpatialZoneEnergyAnalysisPSet(IFCFile file, El int isDaylitZone = 0; if (ParameterUtil.GetIntValueFromElement(element, "Is Daylit Zone", out isDaylitZone) != null) { - IFCData paramVal = Revit.IFC.Export.Toolkit.IFCDataUtil.CreateAsBoolean(isDaylitZone != 0); + IFCData paramVal = IFCDataUtil.CreateAsBoolean(isDaylitZone != 0); IFCAnyHandle propSingleValue = IFCInstanceExporter.CreatePropertySingleValue(file, "IsDaylitZone", null, paramVal, null); properties.Add(propSingleValue); } @@ -1150,7 +1163,7 @@ static private IFCAnyHandle CreateSpatialZoneEnergyAnalysisPSet(IFCFile file, El int numberOfDaylightSensors = 0; if (ParameterUtil.GetIntValueFromElement(element, "Number of Daylight Sensors", out numberOfDaylightSensors) != null) { - IFCData paramVal = Revit.IFC.Export.Toolkit.IFCDataUtil.CreateAsInteger(numberOfDaylightSensors); + IFCData paramVal = IFCDataUtil.CreateAsInteger(numberOfDaylightSensors); IFCAnyHandle propSingleValue = IFCInstanceExporter.CreatePropertySingleValue(file, "NumberOfDaylightSensors", null, paramVal, null); properties.Add(propSingleValue); } @@ -1159,15 +1172,14 @@ static private IFCAnyHandle CreateSpatialZoneEnergyAnalysisPSet(IFCFile file, El if (ParameterUtil.GetDoubleValueFromElement(element, "Design Illuminance", out designIlluminance) != null) { double scaledValue = UnitUtil.ScaleIlluminance(designIlluminance); - IFCData paramVal = Revit.IFC.Export.Toolkit.IFCDataUtil.CreateAsReal(designIlluminance); - IFCAnyHandle unitHnd = !ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView ? ExporterCacheManager.UnitsCache["LUX"] : null; - IFCAnyHandle propSingleValue = IFCInstanceExporter.CreatePropertySingleValue(file, "DesignIlluminance", null, paramVal, unitHnd); + IFCData paramVal = IFCDataUtil.CreateAsIlluminanceMeasure(designIlluminance); + IFCAnyHandle propSingleValue = IFCInstanceExporter.CreatePropertySingleValue(file, "DesignIlluminance", null, paramVal, null); properties.Add(propSingleValue); } if (ParameterUtil.GetStringValueFromElement(element, "Lighting Controls Type", out paramValue) != null) { - IFCData paramVal = Revit.IFC.Export.Toolkit.IFCDataUtil.CreateAsLabel(paramValue); + IFCData paramVal = IFCDataUtil.CreateAsLabel(paramValue); IFCAnyHandle propSingleValue = IFCInstanceExporter.CreatePropertySingleValue(file, "LightingControlsType", null, paramVal, null); properties.Add(propSingleValue); } @@ -1183,131 +1195,13 @@ static private IFCAnyHandle CreateSpatialZoneEnergyAnalysisPSet(IFCFile file, El return null; } - - /// - /// Get the name of the net planned area property, depending on the current schema, for levels and zones. - /// - /// The name of the net planned area property. - /// Note that PSet_SpaceCommon has had the property "NetPlannedArea" since IFC2x3. - static public string GetLevelAndZoneNetPlannedAreaName() - { - return ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4 ? "NetAreaPlanned" : "NetPlannedArea"; - } - - /// - /// Get the name of the gross planned area property, depending on the current schema, for levels and zones. - /// - /// The name of the net planned area property. - /// Note that PSet_SpaceCommon has had the property "GrossPlannedArea" since IFC2x3. - static public string GetLevelAndZoneGrossPlannedAreaName() - { - return ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4 ? "GrossAreaPlanned" : "GrossPlannedArea"; - } - /// /// Creates zone common property set. /// - /// The exporter. /// The file. /// The element. + /// The index to use for the shared parameter names. /// The handle. - static private IFCAnyHandle CreateZoneCommonPSet(ExporterIFC exporterIFC, IFCFile file, Element element) - { - // Property Sets. We don't use the generic Property Set mechanism because Zones aren't "real" elements. - HashSet properties = new HashSet(); - - IFCAnyHandle propSingleValue = PropertyUtil.CreateLabelPropertyFromElement(file, element, - "ZoneCategory", BuiltInParameter.INVALID, "Category", PropertyValueType.SingleValue, null); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propSingleValue)) - { - properties.Add(propSingleValue); - } - - string grossPlannedAreaName = GetLevelAndZoneGrossPlannedAreaName(); - propSingleValue = PropertyUtil.CreateAreaMeasurePropertyFromElement(file, exporterIFC, element, - "Pset_ZoneCommon." + grossPlannedAreaName, BuiltInParameter.INVALID, grossPlannedAreaName, PropertyValueType.SingleValue); - if (IFCAnyHandleUtil.IsNullOrHasNoValue(propSingleValue)) - { - // For backward compatibility - propSingleValue = PropertyUtil.CreateAreaMeasurePropertyFromElement(file, exporterIFC, element, - "Zone" + grossPlannedAreaName, BuiltInParameter.INVALID, grossPlannedAreaName, PropertyValueType.SingleValue); - } - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propSingleValue)) - properties.Add(propSingleValue); - - string netPlannedAreaName = GetLevelAndZoneNetPlannedAreaName(); - propSingleValue = PropertyUtil.CreateAreaMeasurePropertyFromElement(file, exporterIFC, element, - "Pset_ZoneCommon." + netPlannedAreaName, BuiltInParameter.INVALID, netPlannedAreaName, PropertyValueType.SingleValue); - if (IFCAnyHandleUtil.IsNullOrHasNoValue(propSingleValue)) - { - // For backward compatibility - propSingleValue = PropertyUtil.CreateAreaMeasurePropertyFromElement(file, exporterIFC, element, - "Zone" + netPlannedAreaName, BuiltInParameter.INVALID, netPlannedAreaName, PropertyValueType.SingleValue); - } - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propSingleValue)) - properties.Add(propSingleValue); - - propSingleValue = PropertyUtil.CreateBooleanPropertyFromElement(file, element, - "Pset_ZoneCommon.PubliclyAccessible", "PubliclyAccessible", PropertyValueType.SingleValue); - if (IFCAnyHandleUtil.IsNullOrHasNoValue(propSingleValue)) - { - propSingleValue = PropertyUtil.CreateBooleanPropertyFromElement(file, element, - "ZonePubliclyAccessible", "PubliclyAccessible", PropertyValueType.SingleValue); - } - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propSingleValue)) - { - properties.Add(propSingleValue); - } - - propSingleValue = PropertyUtil.CreateBooleanPropertyFromElement(file, element, - "Pset_ZoneCommon.HandicapAccessible", "HandicapAccessible", PropertyValueType.SingleValue); - if (IFCAnyHandleUtil.IsNullOrHasNoValue(propSingleValue)) - { - propSingleValue = PropertyUtil.CreateBooleanPropertyFromElement(file, element, - "ZoneHandicapAccessible", "HandicapAccessible", PropertyValueType.SingleValue); - - } - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propSingleValue)) - { - properties.Add(propSingleValue); - } - - propSingleValue = PropertyUtil.CreateBooleanPropertyFromElement(file, element, - "Pset_ZoneCommon.IsExternal", "IsExternal", PropertyValueType.SingleValue); - if (IFCAnyHandleUtil.IsNullOrHasNoValue(propSingleValue)) - { - propSingleValue = PropertyUtil.CreateBooleanPropertyFromElement(file, element, - "ZoneIsExternal", "IsExternal", PropertyValueType.SingleValue); - - } - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propSingleValue)) - { - properties.Add(propSingleValue); - } - - propSingleValue = PropertyUtil.CreateIdentifierPropertyFromElement(file, element, - "Pset_ZoneCommon.Reference", BuiltInParameter.INVALID, "Reference", PropertyValueType.SingleValue); - if (IFCAnyHandleUtil.IsNullOrHasNoValue(propSingleValue)) - { - propSingleValue = PropertyUtil.CreateIdentifierPropertyFromElement(file, element, - "ZoneReference", BuiltInParameter.INVALID, "Reference", PropertyValueType.SingleValue); - } - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propSingleValue)) - { - properties.Add(propSingleValue); - } - - if (properties.Count > 0) - { - string psetGuid = GUIDUtil.GenerateIFCGuidFrom( - GUIDUtil.CreateGUIDString(element, "Pset_ZoneCommon")); - return IFCInstanceExporter.CreatePropertySet(file, psetGuid, - ExporterCacheManager.OwnerHistoryHandle, "Pset_ZoneCommon", null, properties); - } - - return null; - } - /// /// Creates the ePset_SpaceOccupant. /// @@ -1322,14 +1216,14 @@ private static IFCAnyHandle CreatePSetSpaceOccupant(IFCFile file, Element elemen string paramValue = ""; if (ParameterUtil.GetStringValueFromElement(element, "Space Occupant Organization Abbreviation", out paramValue) != null) { - IFCData paramVal = Revit.IFC.Export.Toolkit.IFCDataUtil.CreateAsLabel(paramValue); + IFCData paramVal = IFCDataUtil.CreateAsLabel(paramValue); IFCAnyHandle propSingleValue = IFCInstanceExporter.CreatePropertySingleValue(file, "SpaceOccupantOrganizationAbbreviation", null, paramVal, null); properties.Add(propSingleValue); } if (ParameterUtil.GetStringValueFromElement(element, "Space Occupant Organization Name", out paramValue) != null) { - IFCData paramVal = Revit.IFC.Export.Toolkit.IFCDataUtil.CreateAsLabel(paramValue); + IFCData paramVal = IFCDataUtil.CreateAsLabel(paramValue); IFCAnyHandle propSingleValue = IFCInstanceExporter.CreatePropertySingleValue(file, "SpaceOccupantOrganizationName", null, paramVal, null); properties.Add(propSingleValue); } @@ -1380,10 +1274,13 @@ private static IFCAnyHandle CreatePSetSpaceOccupant(IFCFile file, Element elemen /// The exporterIFC object. /// The IFCFile object. /// The element. - /// The ProductWrapper. - static void CreateSpaceOccupantInfo(IFCFile file, Element element, ProductWrapper productWrapper) + /// The space handle. + public static void CreateSpaceOccupantInfo(IFCFile file, Element element, IFCAnyHandle spaceHnd) { - IFCAnyHandle spaceHnd = productWrapper.GetElementOfType(IFCEntityType.IfcSpace); + if (IFCAnyHandleUtil.IsNullOrHasNoValue(spaceHnd)) + { + return; + } bool exportToCOBIE = ExporterCacheManager.ExportOptionsCache.ExportAsCOBIE; @@ -1447,11 +1344,9 @@ static void CreateSpaceOccupantInfo(IFCFile file, Element element, ProductWrappe } } - static private void CreateGSAInformation(ExporterIFC exporterIFC, Element element, + static private void CreateGSAInformation(IFCFile file, Element element, ZoneInfo zoneInfo, string zoneObjectType) { - IFCFile file = exporterIFC.GetFile(); - bool isSpatialZone = NamingUtil.IsEqualIgnoringCaseAndSpaces(zoneObjectType, "SpatialZone"); if (isSpatialZone) { @@ -1489,13 +1384,16 @@ static void CreateSpaceOccupantInfo(IFCFile file, Element element, ProductWrappe /// /// Collect information to create zones and cache them to create when end export. /// - /// The exporterIFC object. /// The IFCFile object. /// The element. - /// The ProductWrapper. - static void CreateZoneInfos(ExporterIFC exporterIFC, IFCFile file, Element element, - ProductWrapper productWrapper) + /// The space handle. + static public void CreateZoneInfos(IFCFile file, Element element, IFCAnyHandle spaceHandle) { + if (IFCAnyHandleUtil.IsNullOrHasNoValue(spaceHandle)) + { + return; + } + bool exportToCOBIE = ExporterCacheManager.ExportOptionsCache.ExportAsCOBIE; // Extra zone information, since Revit doesn't have architectural zones. @@ -1514,13 +1412,11 @@ static void CreateSpaceOccupantInfo(IFCFile file, Element element, ProductWrappe string zoneClassificationCode = zoneInfoFinder.GetPropZoneValue(ZoneInfoLabel.ClassificationCode); - IFCAnyHandle roomHandle = productWrapper.GetElementOfType(IFCEntityType.IfcSpace); - ZoneInfo zoneInfo = ExporterCacheManager.ZoneInfoCache.Find(zoneName); if (zoneInfo == null) { - IFCAnyHandle zoneCommonPropertySetHandle = CreateZoneCommonPSet(exporterIFC, file, element); - zoneInfo = new ZoneInfo(zoneInfoFinder, roomHandle, zoneCommonPropertySetHandle); + zoneInfo = new ZoneInfo(zoneInfoFinder, spaceHandle); + zoneInfo.CollectZoneCommonPSetData(file, element, zoneInfoFinder.CurrentZoneNumber); zoneInfo.ConditionalAddClassification(file, zoneClassificationCode); ExporterCacheManager.ZoneInfoCache.Register(zoneName, zoneInfo); } @@ -1528,19 +1424,31 @@ static void CreateSpaceOccupantInfo(IFCFile file, Element element, ProductWrappe { // If description, long name or object type were empty, overwrite. zoneInfo.UpdateZoneInfo(zoneInfoFinder); - zoneInfo.RoomHandles.Add(roomHandle); + zoneInfo.RoomHandles.Add(spaceHandle); + zoneInfo.CollectZoneCommonPSetData(file, element, zoneInfoFinder.CurrentZoneNumber); zoneInfo.ConditionalAddClassification(file, zoneClassificationCode); - - if (IFCAnyHandleUtil.IsNullOrHasNoValue(zoneInfo.ZoneCommonProperySetHandle)) - zoneInfo.ZoneCommonProperySetHandle = CreateZoneCommonPSet(exporterIFC, file, element); } if (exportToCOBIE) { string zoneObjectType = zoneInfoFinder.GetPropZoneValue(ZoneInfoLabel.ObjectType); - CreateGSAInformation(exporterIFC, element, zoneInfo, zoneObjectType); + CreateGSAInformation(file, element, zoneInfo, zoneObjectType); } } while (zoneInfoFinder.IncrementCount()); // prevent infinite loop. } + + /// + /// Determine if the export instance type is compatible with IfcZone. + /// + /// The export type to check. + /// True if non-null, and an entity instance type that can go in a zone. + public static bool IsZoneCompatible(IFCExportInfoPair exportType) + { + if (exportType == null) + return false; + + return exportType.ExportInstance == IFCEntityType.IfcSpace || + exportType.ExportInstance == IFCEntityType.IfcSpatialZone; + } } } \ No newline at end of file diff --git a/Source/Revit.IFC.Export/Exporter/StairsExporter.cs b/Source/Revit.IFC.Export/Exporter/StairsExporter.cs index cefb21da..c05cc07a 100644 --- a/Source/Revit.IFC.Export/Exporter/StairsExporter.cs +++ b/Source/Revit.IFC.Export/Exporter/StairsExporter.cs @@ -884,7 +884,7 @@ public static List GetFlightsOffsetList(ExporterIFC exporterIFC, Stairs List components = new List(); IList componentExtrusionData = new List(); IFCAnyHandle containedStairHnd = IFCInstanceExporter.CreateStair(exporterIFC, stair, containedStairGuid, ownerHistory, - containedStairLocalPlacement, representation, exportType.ValidatedPredefinedType); + containedStairLocalPlacement, representation, exportType.GetPredefinedTypeOrDefault()); // Create appropriate type @@ -900,7 +900,7 @@ public static List GetFlightsOffsetList(ExporterIFC exporterIFC, Stairs IFCAnyHandle localPlacement = ecData.GetLocalPlacement(); IFCAnyHandle stairContainerHnd = IFCInstanceExporter.CreateStair(exporterIFC, stair, stairGuid, ownerHistory, - localPlacement, null, exportType.ValidatedPredefinedType); + localPlacement, null, exportType.GetPredefinedTypeOrDefault()); // Create appropriate type for the container //string contPredefType = GetValidatedStairType(stair as Stairs, ifcEnumType); @@ -974,14 +974,16 @@ public static List GetFlightsOffsetList(ExporterIFC exporterIFC, Stairs IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; string stairGUID = GUIDUtil.CreateGUID(stair); IFCAnyHandle stairLocalPlacement = placementSetter.LocalPlacement; - //string stairType = GetIFCStairType(ifcEnumType); - string predefType = GetValidatedStairType(stair, null); + + string predefinedType = ifcEnumType; + if (string.IsNullOrWhiteSpace(predefinedType)) + predefinedType = GetValidatedStairType(stair, null); // override by stair components if predefined type is not set IFCAnyHandle stairContainerHnd = IFCInstanceExporter.CreateStair(exporterIFC, stair, stairGUID, ownerHistory, - stairLocalPlacement, null, predefType); + stairLocalPlacement, null, predefinedType); // Create appropriate type - IFCExportInfoPair exportType = new IFCExportInfoPair(IFCEntityType.IfcStair, predefType); + IFCExportInfoPair exportType = new IFCExportInfoPair(IFCEntityType.IfcStair, predefinedType); IFCAnyHandle stairTypeHnd = ExporterUtil.CreateGenericTypeFromElement(stair, exportType, exporterIFC.GetFile(), productWrapper); ExporterCacheManager.TypeRelationsCache.Add(stairTypeHnd, stairContainerHnd); @@ -996,67 +998,66 @@ public static List GetFlightsOffsetList(ExporterIFC exporterIFC, Stairs { index++; StairsRun run = doc.GetElement(runId) as StairsRun; - - using (IFCExportBodyParams ecData = new IFCExportBodyParams()) - { - ecData.AllowVerticalOffsetOfBReps = false; - ecData.SetLocalPlacement(ExporterUtil.CreateLocalPlacement(file, placementSetter.LocalPlacement, null)); - ecData.ReuseLocalPlacement = true; - ecData.IFCCADLayerOverride = ifcCADLayer; - GeometryElement runGeometryElement = run.get_Geometry(geomOptions); - BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow); - BodyData bodyData = BodyExporter.ExportBody(exporterIFC, run, categoryId, ElementId.InvalidElementId, runGeometryElement, - bodyExporterOptions, ecData); + IFCExportBodyParams ecData = new IFCExportBodyParams(); + ecData.AllowVerticalOffsetOfBReps = false; + ecData.SetLocalPlacement(ExporterUtil.CreateLocalPlacement(file, placementSetter.LocalPlacement, null)); + ecData.ReuseLocalPlacement = true; + ecData.IFCCADLayerOverride = ifcCADLayer; + GeometryElement runGeometryElement = run.get_Geometry(geomOptions); - IFCAnyHandle bodyRep = bodyData.RepresentationHnd; - if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep)) - { - ecData.ClearOpenings(); - continue; - } + BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow); + BodyData bodyData = BodyExporter.ExportBody(exporterIFC, run, categoryId, ElementId.InvalidElementId, runGeometryElement, + bodyExporterOptions, ecData); - IList reps = new List(); - reps.Add(bodyRep); + IFCAnyHandle bodyRep = bodyData.RepresentationHnd; + if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep)) + { + ecData.ClearOpenings(); + ecData.Dispose(); + continue; + } - if (!ExporterCacheManager.ExportOptionsCache.ExportAsCoordinationView2) - { - CreateWalkingLineAndFootprint(exporterIFC, run, bodyData, categoryId, trf, ref reps); - } + IList reps = new List(); + reps.Add(bodyRep); - Transform boundingBoxTrf = (bodyData.OffsetTransform == null) ? Transform.Identity : bodyData.OffsetTransform.Inverse; - IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, runGeometryElement, boundingBoxTrf); - if (boundingBoxRep != null) - reps.Add(boundingBoxRep); + if (!ExporterCacheManager.ExportOptionsCache.ExportAsCoordinationView2) + { + CreateWalkingLineAndFootprint(exporterIFC, run, bodyData, categoryId, trf, ref reps); + } - IFCAnyHandle representation = IFCInstanceExporter.CreateProductDefinitionShape(exporterIFC.GetFile(), null, null, reps); + Transform boundingBoxTrf = (bodyData.OffsetTransform == null) ? Transform.Identity : bodyData.OffsetTransform.Inverse; + IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, runGeometryElement, boundingBoxTrf); + if (boundingBoxRep != null) + reps.Add(boundingBoxRep); - string runGUID = GUIDUtil.CreateGUID(run); - string origRunName = IFCAnyHandleUtil.GetStringAttribute(stairContainerHnd, "Name") + " Run " + index; - string runName = NamingUtil.GetNameOverride(run, origRunName); + IFCAnyHandle representation = IFCInstanceExporter.CreateProductDefinitionShape(exporterIFC.GetFile(), null, null, reps); - IFCAnyHandle runLocalPlacement = ecData.GetLocalPlacement(); - string runElementTag = NamingUtil.GetTagOverride(run); + string runGUID = GUIDUtil.CreateGUID(run); + string origRunName = IFCAnyHandleUtil.GetStringAttribute(stairContainerHnd, "Name") + " Run " + index; + string runName = NamingUtil.GetNameOverride(run, origRunName); - string flightPredefType = GetValidatedStairFlightType(run); + IFCAnyHandle runLocalPlacement = ecData.GetLocalPlacement(); + string runElementTag = NamingUtil.GetTagOverride(run); - IFCAnyHandle stairFlightHnd = IFCInstanceExporter.CreateStairFlight(exporterIFC, run, runGUID, ownerHistory, runLocalPlacement, - representation, run.ActualRisersNumber, run.ActualTreadsNumber, stair.ActualRiserHeight, stair.ActualTreadDepth, flightPredefType); - IFCAnyHandleUtil.OverrideNameAttribute(stairFlightHnd, runName); - // Create type - IFCExportInfoPair flightEportType = new IFCExportInfoPair(IFCEntityType.IfcStairFlight, flightPredefType); - IFCAnyHandle flightTypeHnd = ExporterUtil.CreateGenericTypeFromElement(run, flightEportType, exporterIFC.GetFile(), productWrapper); - ExporterCacheManager.TypeRelationsCache.Add(flightTypeHnd, stairFlightHnd); + string flightPredefType = GetValidatedStairFlightType(run); - componentHandles.Add(stairFlightHnd); - componentExtrusionData.Add(ecData); + IFCAnyHandle stairFlightHnd = IFCInstanceExporter.CreateStairFlight(exporterIFC, run, runGUID, ownerHistory, runLocalPlacement, + representation, run.ActualRisersNumber, run.ActualTreadsNumber, stair.ActualRiserHeight, stair.ActualTreadDepth, flightPredefType); + IFCAnyHandleUtil.OverrideNameAttribute(stairFlightHnd, runName); + // Create type + IFCExportInfoPair flightEportType = new IFCExportInfoPair(IFCEntityType.IfcStairFlight, flightPredefType); + IFCAnyHandle flightTypeHnd = ExporterUtil.CreateGenericTypeFromElement(run, flightEportType, exporterIFC.GetFile(), productWrapper); + ExporterCacheManager.TypeRelationsCache.Add(flightTypeHnd, stairFlightHnd); - CategoryUtil.CreateMaterialAssociation(exporterIFC, stairFlightHnd, bodyData.MaterialIds); + componentHandles.Add(stairFlightHnd); + componentExtrusionData.Add(ecData); - productWrapper.AddElement(run, stairFlightHnd, placementSetter.LevelInfo, ecData, false, flightEportType); + CategoryUtil.CreateMaterialAssociation(exporterIFC, stairFlightHnd, bodyData.MaterialIds); - ExporterCacheManager.HandleToElementCache.Register(stairFlightHnd, run.Id); - } + productWrapper.AddElement(run, stairFlightHnd, placementSetter.LevelInfo, ecData, false, flightEportType); + + ExporterCacheManager.HandleToElementCache.Register(stairFlightHnd, run.Id); } // Get List of landings to export their geometry. @@ -1067,64 +1068,63 @@ public static List GetFlightsOffsetList(ExporterIFC exporterIFC, Stairs index++; StairsLanding landing = doc.GetElement(landingId) as StairsLanding; - using (IFCExportBodyParams ecData = new IFCExportBodyParams()) + IFCExportBodyParams ecData = new IFCExportBodyParams(); + ecData.AllowVerticalOffsetOfBReps = false; + ecData.SetLocalPlacement(ExporterUtil.CreateLocalPlacement(file, placementSetter.LocalPlacement, null)); + ecData.ReuseLocalPlacement = true; + + GeometryElement landingGeometryElement = landing.get_Geometry(geomOptions); + + BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow); + BodyData bodyData = BodyExporter.ExportBody(exporterIFC, landing, categoryId, ElementId.InvalidElementId, landingGeometryElement, + bodyExporterOptions, ecData); + + IFCAnyHandle bodyRep = bodyData.RepresentationHnd; + if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep)) { - ecData.AllowVerticalOffsetOfBReps = false; - ecData.SetLocalPlacement(ExporterUtil.CreateLocalPlacement(file, placementSetter.LocalPlacement, null)); - ecData.ReuseLocalPlacement = true; + ecData.ClearOpenings(); + ecData.Dispose(); + continue; + } - GeometryElement landingGeometryElement = landing.get_Geometry(geomOptions); + // create Boundary rep. + IList reps = new List(); + reps.Add(bodyRep); - BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow); - BodyData bodyData = BodyExporter.ExportBody(exporterIFC, landing, categoryId, ElementId.InvalidElementId, landingGeometryElement, - bodyExporterOptions, ecData); + if (!ExporterCacheManager.ExportOptionsCache.ExportAsCoordinationView2) + { + CreateWalkingLineAndFootprint(exporterIFC, landing, bodyData, categoryId, trf, ref reps); + } - IFCAnyHandle bodyRep = bodyData.RepresentationHnd; - if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep)) - { - ecData.ClearOpenings(); - continue; - } + Transform boundingBoxTrf = (bodyData.OffsetTransform == null) ? Transform.Identity : bodyData.OffsetTransform.Inverse; + IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, landingGeometryElement, boundingBoxTrf); + if (boundingBoxRep != null) + reps.Add(boundingBoxRep); - // create Boundary rep. - IList reps = new List(); - reps.Add(bodyRep); + string landingGUID = GUIDUtil.CreateGUID(landing); + string origLandingName = IFCAnyHandleUtil.GetStringAttribute(stairContainerHnd, "Name") + " Landing " + index; + string landingName = NamingUtil.GetNameOverride(landing, origLandingName); + IFCAnyHandle landingLocalPlacement = ecData.GetLocalPlacement(); - if (!ExporterCacheManager.ExportOptionsCache.ExportAsCoordinationView2) - { - CreateWalkingLineAndFootprint(exporterIFC, landing, bodyData, categoryId, trf, ref reps); - } + IFCAnyHandle representation = IFCInstanceExporter.CreateProductDefinitionShape(exporterIFC.GetFile(), null, null, reps); - Transform boundingBoxTrf = (bodyData.OffsetTransform == null) ? Transform.Identity : bodyData.OffsetTransform.Inverse; - IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, landingGeometryElement, boundingBoxTrf); - if (boundingBoxRep != null) - reps.Add(boundingBoxRep); - - string landingGUID = GUIDUtil.CreateGUID(landing); - string origLandingName = IFCAnyHandleUtil.GetStringAttribute(stairContainerHnd, "Name") + " Landing " + index; - string landingName = NamingUtil.GetNameOverride(landing, origLandingName); - IFCAnyHandle landingLocalPlacement = ecData.GetLocalPlacement(); - - IFCAnyHandle representation = IFCInstanceExporter.CreateProductDefinitionShape(exporterIFC.GetFile(), null, null, reps); - - string landingPredefinedType = "LANDING"; - IFCAnyHandle landingHnd = IFCInstanceExporter.CreateSlab(exporterIFC, landing, landingGUID, ownerHistory, - landingLocalPlacement, representation, landingPredefinedType); - IFCAnyHandleUtil.OverrideNameAttribute(landingHnd, landingName); - - // Create type - IFCExportInfoPair landingExportType = new IFCExportInfoPair(IFCEntityType.IfcSlab, landingPredefinedType); - IFCAnyHandle landingTypeHnd = ExporterUtil.CreateGenericTypeFromElement(landing, landingExportType, exporterIFC.GetFile(), productWrapper); - ExporterCacheManager.TypeRelationsCache.Add(landingTypeHnd, landingHnd); - - componentHandles.Add(landingHnd); - componentExtrusionData.Add(ecData); + string landingPredefinedType = "LANDING"; + IFCAnyHandle landingHnd = IFCInstanceExporter.CreateSlab(exporterIFC, landing, landingGUID, ownerHistory, + landingLocalPlacement, representation, landingPredefinedType); + IFCAnyHandleUtil.OverrideNameAttribute(landingHnd, landingName); - CategoryUtil.CreateMaterialAssociation(exporterIFC, landingHnd, bodyData.MaterialIds); + // Create type + IFCExportInfoPair landingExportType = new IFCExportInfoPair(IFCEntityType.IfcSlab, landingPredefinedType); + IFCAnyHandle landingTypeHnd = ExporterUtil.CreateGenericTypeFromElement(landing, landingExportType, exporterIFC.GetFile(), productWrapper); + ExporterCacheManager.TypeRelationsCache.Add(landingTypeHnd, landingHnd); - productWrapper.AddElement(landing, landingHnd, placementSetter.LevelInfo, ecData, false, landingExportType); - ExporterCacheManager.HandleToElementCache.Register(landingHnd, landing.Id); - } + componentHandles.Add(landingHnd); + componentExtrusionData.Add(ecData); + + CategoryUtil.CreateMaterialAssociation(exporterIFC, landingHnd, bodyData.MaterialIds); + + productWrapper.AddElement(landing, landingHnd, placementSetter.LevelInfo, ecData, false, landingExportType); + ExporterCacheManager.HandleToElementCache.Register(landingHnd, landing.Id); } // Get List of supports to export their geometry. Supports are not exposed to API, so export as generic Element. @@ -1135,45 +1135,44 @@ public static List GetFlightsOffsetList(ExporterIFC exporterIFC, Stairs index++; Element support = doc.GetElement(supportId); - using (IFCExportBodyParams ecData = new IFCExportBodyParams()) - { - ecData.SetLocalPlacement(ExporterUtil.CreateLocalPlacement(file, placementSetter.LocalPlacement, null)); - ecData.ReuseLocalPlacement = true; - ecData.IFCCADLayerOverride = ifcCADLayer; + IFCExportBodyParams ecData = new IFCExportBodyParams(); + ecData.SetLocalPlacement(ExporterUtil.CreateLocalPlacement(file, placementSetter.LocalPlacement, null)); + ecData.ReuseLocalPlacement = true; + ecData.IFCCADLayerOverride = ifcCADLayer; - GeometryElement supportGeometryElement = support.get_Geometry(geomOptions); - BodyData bodyData; - BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow); - IFCAnyHandle representation = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, - support, categoryId, supportGeometryElement, bodyExporterOptions, null, ecData, out bodyData, instanceGeometry: true); + GeometryElement supportGeometryElement = support.get_Geometry(geomOptions); + BodyData bodyData; + BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow); + IFCAnyHandle representation = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, + support, categoryId, supportGeometryElement, bodyExporterOptions, null, ecData, out bodyData, instanceGeometry: true); - if (IFCAnyHandleUtil.IsNullOrHasNoValue(representation)) - { - ecData.ClearOpenings(); - continue; - } + if (IFCAnyHandleUtil.IsNullOrHasNoValue(representation)) + { + ecData.ClearOpenings(); + ecData.Dispose(); + continue; + } - string supportGUID = GUIDUtil.CreateGUID(support); - string origSupportName = IFCAnyHandleUtil.GetStringAttribute(stairContainerHnd, "Name") + " Stringer " + index; - string supportName = NamingUtil.GetNameOverride(support, origSupportName); - IFCAnyHandle supportLocalPlacement = ecData.GetLocalPlacement(); + string supportGUID = GUIDUtil.CreateGUID(support); + string origSupportName = IFCAnyHandleUtil.GetStringAttribute(stairContainerHnd, "Name") + " Stringer " + index; + string supportName = NamingUtil.GetNameOverride(support, origSupportName); + IFCAnyHandle supportLocalPlacement = ecData.GetLocalPlacement(); - string stringerPredefType = "STRINGER"; - IFCExportInfoPair stringerExportInfo = new IFCExportInfoPair(IFCEntityType.IfcMember, stringerPredefType); - IFCAnyHandle type = GetMemberTypeHandle(exporterIFC, support); + string stringerPredefType = "STRINGER"; + IFCExportInfoPair stringerExportInfo = new IFCExportInfoPair(IFCEntityType.IfcMember, stringerPredefType); + IFCAnyHandle type = GetMemberTypeHandle(exporterIFC, support); - IFCAnyHandle supportHnd = IFCInstanceExporter.CreateMember(exporterIFC, support, supportGUID, ownerHistory, - supportLocalPlacement, representation, stringerPredefType); - IFCAnyHandleUtil.OverrideNameAttribute(supportHnd, supportName); - componentHandles.Add(supportHnd); - componentExtrusionData.Add(ecData); + IFCAnyHandle supportHnd = IFCInstanceExporter.CreateMember(exporterIFC, support, supportGUID, ownerHistory, + supportLocalPlacement, representation, stringerPredefType); + IFCAnyHandleUtil.OverrideNameAttribute(supportHnd, supportName); + componentHandles.Add(supportHnd); + componentExtrusionData.Add(ecData); - CategoryUtil.CreateMaterialAssociation(exporterIFC, supportHnd, bodyData.MaterialIds); + CategoryUtil.CreateMaterialAssociation(exporterIFC, supportHnd, bodyData.MaterialIds); - productWrapper.AddElement(support, supportHnd, placementSetter.LevelInfo, ecData, false, stringerExportInfo); + productWrapper.AddElement(support, supportHnd, placementSetter.LevelInfo, ecData, false, stringerExportInfo); - ExporterCacheManager.TypeRelationsCache.Add(type, supportHnd); - } + ExporterCacheManager.TypeRelationsCache.Add(type, supportHnd); } StairRampContainerInfo stairRampInfo = new StairRampContainerInfo(stairContainerHnd, componentHandles, stairLocalPlacement); @@ -1285,11 +1284,11 @@ public static List GetFlightsOffsetList(ExporterIFC exporterIFC, Stairs HashSet flightHnds = new HashSet(); List representations = new List(); - if ((ii < walkingLineCount) && !IFCAnyHandleUtil.IsNullOrHasNoValue(walkingLineReps[ii])) - representations.Add(walkingLineReps[ii]); + if (ii < walkingLineCount) + representations.AddIfNotNull(walkingLineReps[ii]); - if ((ii < boundaryRepCount) && !IFCAnyHandleUtil.IsNullOrHasNoValue(boundaryReps[ii])) - representations.Add(boundaryReps[ii]); + if (ii < boundaryRepCount) + representations.AddIfNotNull(boundaryReps[ii]); representations.Add(bodyRep); @@ -1344,7 +1343,7 @@ public static List GetFlightsOffsetList(ExporterIFC exporterIFC, Stairs flightHnd = IFCInstanceExporter.CreateRampFlight(exporterIFC, legacyStair, flightCompGUID, ExporterCacheManager.OwnerHistoryHandle, newLocalPlacement, newProdRep, ifcType); components[compIdx].Add(flightHnd); - exportInfo.SetValueWithPair(IFCEntityType.IfcRampFlight, ifcType); + exportInfo.SetByTypeAndPredefinedType(IFCEntityType.IfcRampFlight, ifcType); } else { @@ -1354,7 +1353,7 @@ public static List GetFlightsOffsetList(ExporterIFC exporterIFC, Stairs flightHnd = IFCInstanceExporter.CreateStairFlight(exporterIFC, legacyStair, flightCompGUID, ExporterCacheManager.OwnerHistoryHandle, newLocalPlacement, newProdRep, numRisers[ii], numTreads[ii], riserHeight, treadsLength[ii], ifcType); components[compIdx].Add(flightHnd); - exportInfo.SetValueWithPair(IFCEntityType.IfcStairFlight, ifcType); + exportInfo.SetByTypeAndPredefinedType(IFCEntityType.IfcStairFlight, ifcType); } IFCAnyHandleUtil.OverrideNameAttribute(flightHnd, stairName); @@ -1383,11 +1382,11 @@ public static List GetFlightsOffsetList(ExporterIFC exporterIFC, Stairs } List representations = new List(); - if (((ii + runCount) < walkingLineCount) && !IFCAnyHandleUtil.IsNullOrHasNoValue(walkingLineReps[ii + runCount])) - representations.Add(walkingLineReps[ii + runCount]); + if ((ii + runCount) < walkingLineCount) + representations.AddIfNotNull(walkingLineReps[ii + runCount]); - if (((ii + runCount) < boundaryRepCount) && !IFCAnyHandleUtil.IsNullOrHasNoValue(boundaryReps[ii + runCount])) - representations.Add(boundaryReps[ii + runCount]); + if ((ii + runCount) < boundaryRepCount) + representations.AddIfNotNull(boundaryReps[ii + runCount]); representations.Add(bodyRep); @@ -1501,11 +1500,14 @@ public static List GetFlightsOffsetList(ExporterIFC exporterIFC, Stairs if (isRamp) { string rampType = RampExporter.GetIFCRampType(ifcEnumType); - string stairName = NamingUtil.GetIFCName(legacyStair); + string rampName = NamingUtil.GetIFCName(legacyStair); IFCAnyHandle containedRampHnd = IFCInstanceExporter.CreateRamp(exporterIFC, legacyStair, GUIDUtil.CreateGUID(legacyStair), ExporterCacheManager.OwnerHistoryHandle, placementSetter.LocalPlacement, null, rampType); - IFCAnyHandleUtil.OverrideNameAttribute(containedRampHnd, stairName); + IFCAnyHandleUtil.OverrideNameAttribute(containedRampHnd, rampName); IFCExportInfoPair exportInfo = new IFCExportInfoPair(IFCEntityType.IfcRamp, rampType); + IFCAnyHandle typeHnd = ExporterUtil.CreateGenericTypeFromElement(legacyStair, exportInfo, file, productWrapper); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(typeHnd)) + ExporterCacheManager.TypeRelationsCache.Add(typeHnd, containedRampHnd); productWrapper.AddElement(legacyStair, containedRampHnd, placementSetter.LevelInfo, ifcECData, true, exportInfo); createdStairs.Add(containedRampHnd); } @@ -1517,6 +1519,9 @@ public static List GetFlightsOffsetList(ExporterIFC exporterIFC, Stairs placementSetter.LocalPlacement, null, stairType); IFCAnyHandleUtil.OverrideNameAttribute(containedStairHnd, stairName); IFCExportInfoPair exportInfo = new IFCExportInfoPair(IFCEntityType.IfcStair, stairType); + IFCAnyHandle typeHnd = ExporterUtil.CreateGenericTypeFromElement(legacyStair, exportInfo, file, productWrapper); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(typeHnd)) + ExporterCacheManager.TypeRelationsCache.Add(typeHnd, containedStairHnd); productWrapper.AddElement(legacyStair, containedStairHnd, placementSetter.LevelInfo, ifcECData, true, exportInfo); createdStairs.Add(containedStairHnd); } @@ -1613,11 +1618,11 @@ public static List GetFlightsOffsetList(ExporterIFC exporterIFC, Stairs public static void Export(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, ProductWrapper productWrapper) { // Check the intended IFC entity or type name is in the exclude list specified in the UI - Common.Enums.IFCEntityType elementClassTypeEnum = Common.Enums.IFCEntityType.IfcStair; - if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) + if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(IFCEntityType.IfcStair)) return; - string ifcEnumType = ExporterUtil.GetIFCTypeFromExportTable(exporterIFC, element); + IFCExportInfoPair exportType = ExporterUtil.GetProductExportType(exporterIFC, element, out _); + string ifcEnumType = exportType.GetPredefinedTypeOrDefault(); IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) @@ -1628,7 +1633,7 @@ public static void Export(ExporterIFC exporterIFC, Element element, GeometryElem List flightOffsets = GetFlightsOffsetList(exporterIFC, stair); if (flightOffsets.Count > 0) { - ExportStairsAsContainer(exporterIFC, ifcEnumType, stair, geometryElement, flightOffsets, productWrapper); + ExportStairsAsContainer(exporterIFC, exportType.PredefinedType, stair, geometryElement, flightOffsets, productWrapper); if (IFCAnyHandleUtil.IsNullOrHasNoValue(productWrapper.GetAnElement())) ExportStairAsSingleGeometry(exporterIFC, ifcEnumType, element, geometryElement, flightOffsets, productWrapper); } @@ -1681,9 +1686,7 @@ static IList CreateBoundaryLineReps(ExporterIFC exporterIFC, IFCLe { if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView) { - IFCAnyHandle curveHnd = GeometryUtil.CreatePolyCurveFromCurve(exporterIFC, curve); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(curveHnd)) - curveSet.Add(curveHnd); + curveSet.AddIfNotNull(GeometryUtil.CreatePolyCurveFromCurve(exporterIFC, curve)); } else { @@ -1691,9 +1694,9 @@ static IList CreateBoundaryLineReps(ExporterIFC exporterIFC, IFCLe ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, curve, XYZ.Zero, false); IList curves = info.GetCurves(); - if (curves.Count == 1 && !IFCAnyHandleUtil.IsNullOrHasNoValue(curves[0])) + if (curves.Count == 1) { - curveSet.Add(curves[0]); + curveSet.AddIfNotNull(curves[0]); } } } @@ -1729,8 +1732,7 @@ static IList CreateWalkLineReps(ExporterIFC exporterIFC, IFCLegacy IFCAnyHandle curve = GeometryUtil.CreateIFCCurveFromCurves(exporterIFC, curves, lcs, projDir); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(curve)) { - HashSet bodyItems = new HashSet(); - bodyItems.Add(curve); + HashSet bodyItems = new HashSet() { curve }; walkLineReps.Add(RepresentationUtil.CreateShapeRepresentation(exporterIFC, legacyStairElem, cateId, contextOfItemsWalkLine, "Axis", "Curve2D", bodyItems)); } @@ -1770,11 +1772,10 @@ private static void CreateWalkingLineAndFootprint(ExporterIFC exporterIFC, Eleme boundaryTrf, runBoundaryProjDir); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(boundaryHnd)) { - HashSet geomSelectSet = new HashSet(); - geomSelectSet.Add(boundaryHnd); + HashSet geomSelectSet = new HashSet() { boundaryHnd }; - HashSet boundaryItems = new HashSet(); - boundaryItems.Add(IFCInstanceExporter.CreateGeometricSet(file, geomSelectSet)); + HashSet boundaryItems = new HashSet() + { IFCInstanceExporter.CreateGeometricSet(file, geomSelectSet) }; IFCAnyHandle boundaryRep = RepresentationUtil.CreateGeometricSetRep(exporterIFC, element, categoryId, "FootPrint", contextOfItemsFootPrint, boundaryItems); @@ -1791,11 +1792,10 @@ private static void CreateWalkingLineAndFootprint(ExporterIFC exporterIFC, Eleme boundaryTrf, runBoundaryProjDir); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(walkingLineHnd)) { - HashSet geomSelectSet = new HashSet(); - geomSelectSet.Add(walkingLineHnd); + HashSet geomSelectSet = new HashSet() { walkingLineHnd }; - HashSet walkingLineItems = new HashSet(); - walkingLineItems.Add(IFCInstanceExporter.CreateGeometricSet(file, geomSelectSet)); + HashSet walkingLineItems = new HashSet() + { IFCInstanceExporter.CreateGeometricSet(file, geomSelectSet) }; IFCAnyHandle walkingLineRep = RepresentationUtil.CreateGeometricSetRep(exporterIFC, element, categoryId, "Axis", contextOfItemsAxis, walkingLineItems); diff --git a/Source/Revit.IFC.Export/Exporter/StructuralMemberExporter.cs b/Source/Revit.IFC.Export/Exporter/StructuralMemberExporter.cs index dbfc2369..0ef68f87 100644 --- a/Source/Revit.IFC.Export/Exporter/StructuralMemberExporter.cs +++ b/Source/Revit.IFC.Export/Exporter/StructuralMemberExporter.cs @@ -194,7 +194,9 @@ public static IFCAnyHandle CreateStructuralMemberAxis(ExporterIFC exporterIFC, E curve = curve.CreateTransformed(offset.Inverse.Multiply(axisInfo.LCSAsTransform)); IDictionary cachePoints = new Dictionary(); - IFCAnyHandle ifcCurveHnd = GeometryUtil.CreateIFCCurveFromRevitCurve(exporterIFC.GetFile(), exporterIFC, curve, true, cachePoints, true); + const GeometryUtil.TrimCurvePreference trimCurvePreference = GeometryUtil.TrimCurvePreference.TrimmedCurve; + IFCAnyHandle ifcCurveHnd = GeometryUtil.CreateIFCCurveFromRevitCurve(exporterIFC.GetFile(), + exporterIFC, curve, true, cachePoints, trimCurvePreference, null); IList axis_items = new List(); if (!(IFCAnyHandleUtil.IsNullOrHasNoValue(ifcCurveHnd))) axis_items.Add(ifcCurveHnd); diff --git a/Source/Revit.IFC.Export/Exporter/SweptSolidExporter.cs b/Source/Revit.IFC.Export/Exporter/SweptSolidExporter.cs index 33c08bb6..2ffe5a69 100644 --- a/Source/Revit.IFC.Export/Exporter/SweptSolidExporter.cs +++ b/Source/Revit.IFC.Export/Exporter/SweptSolidExporter.cs @@ -146,9 +146,11 @@ public static SimpleSweptSolidAnalyzer CanExportAsSweptSolid(ExporterIFC exporte /// The element. /// The solid. /// The normal of the plane that the path lies on. + /// A set of flags for which representations we should generate. + /// True if we should do a coarse parameterization of the directrix. /// The SweptSolidExporter. public static SweptSolidExporter Create(ExporterIFC exporterIFC, Element element, SimpleSweptSolidAnalyzer sweptAnalyzer, GeometryObject geomObject, - GenerateAdditionalInfo addInfo = GenerateAdditionalInfo.GenerateBody) + GenerateAdditionalInfo addInfo, bool isCoarse) { try { @@ -157,7 +159,7 @@ public static SimpleSweptSolidAnalyzer CanExportAsSweptSolid(ExporterIFC exporte SweptSolidExporter sweptSolidExporter = null; - IList faceBoundaryTypes; + IList faceBoundaryTypes; IList faceBoundaries = GeometryUtil.GetFaceBoundaries(sweptAnalyzer.ProfileFace, null, out faceBoundaryTypes); string profileName = null; @@ -202,7 +204,7 @@ public static SimpleSweptSolidAnalyzer CanExportAsSweptSolid(ExporterIFC exporte } else { - sweptSolidExporter.RepresentationItem = CreateSimpleSweptSolid(exporterIFC, profileName, faceBoundaries, sweptAnalyzer.ReferencePlaneNormal, sweptAnalyzer.PathCurve); + sweptSolidExporter.RepresentationItem = CreateSimpleSweptSolid(exporterIFC, profileName, faceBoundaries, sweptAnalyzer.PathCurve); sweptSolidExporter.RepresentationType = ShapeRepresentationType.AdvancedSweptSolid; if ((addInfo & GenerateAdditionalInfo.GenerateFootprint) != 0) { @@ -213,7 +215,8 @@ public static SimpleSweptSolidAnalyzer CanExportAsSweptSolid(ExporterIFC exporte } else { - sweptSolidExporter.Facets = CreateSimpleSweptSolidAsBRep(exporterIFC, profileName, faceBoundaries, sweptAnalyzer.ReferencePlaneNormal, sweptAnalyzer.PathCurve); + sweptSolidExporter.Facets = CreateSimpleSweptSolidAsBRep(exporterIFC, faceBoundaries, + sweptAnalyzer.PathCurve, isCoarse); sweptSolidExporter.RepresentationType = ShapeRepresentationType.Brep; } } @@ -255,7 +258,7 @@ public static IFCAnyHandle CreateSimpleSweptSolid(ExporterIFC exporterIFC, Eleme profileName = type.Name; } - return CreateSimpleSweptSolid(exporterIFC, profileName, faceBoundaries, sweptAnalyzer.ReferencePlaneNormal, sweptAnalyzer.PathCurve); + return CreateSimpleSweptSolid(exporterIFC, profileName, faceBoundaries, sweptAnalyzer.PathCurve); } } catch (Exception) @@ -266,9 +269,9 @@ public static IFCAnyHandle CreateSimpleSweptSolid(ExporterIFC exporterIFC, Eleme return null; } - private static bool CanCreateSimpleSweptSolid(IList profileCurveLoops, XYZ normal, Curve directrix) + private static bool CanCreateSimpleSweptSolid(IList profileCurveLoops, Curve directrix) { - if (directrix == null || normal == null || profileCurveLoops == null || profileCurveLoops.Count == 0) + if (directrix == null || profileCurveLoops == null || profileCurveLoops.Count == 0) return false; if (directrix is Arc) @@ -336,14 +339,14 @@ private static void CreateAxisAndProfileCurveLCS(Curve directrix, double param, /// The path curve. /// The swept solid handle. public static IFCAnyHandle CreateSimpleSweptSolid(ExporterIFC exporterIFC, string profileName, IList profileCurveLoops, - XYZ normal, Curve directrix) + Curve directrix) { // see definition of IfcSurfaceCurveSweptAreaSolid from // http://www.buildingsmart-tech.org/ifc/IFC2x4/rc4/html/schema/ifcgeometricmodelresource/lexical/ifcsurfacecurvesweptareasolid.htm IFCAnyHandle simpleSweptSolidHnd = null; - if (!CanCreateSimpleSweptSolid(profileCurveLoops, normal, directrix)) + if (!CanCreateSimpleSweptSolid(profileCurveLoops, directrix)) return simpleSweptSolidHnd; bool isBound = directrix.IsBound; @@ -363,7 +366,7 @@ private static void CreateAxisAndProfileCurveLCS(Curve directrix, double param, return null; } - if (curveLoops == null || curveLoops.Count == 0) + if ((curveLoops?.Count ?? 0) == 0) return simpleSweptSolidHnd; double startParam = 0.0, endParam = 1.0; @@ -373,28 +376,22 @@ private static void CreateAxisAndProfileCurveLCS(Curve directrix, double param, if (isBound) { // Put the parameters in range of [0, 2*Pi] - double inRangeStarParam = (directrix.GetEndParameter(0) % (2 * Math.PI)); + double inRangeStartParam = (directrix.GetEndParameter(0) % (2 * Math.PI)); double inRangeEndParam = (directrix.GetEndParameter(1) % (2 * Math.PI)); // We want the angle direction is anti-clockwise (+ direction), therefore we will always start with the smaller one - if (inRangeEndParam < inRangeStarParam) + if (inRangeEndParam < inRangeStartParam) { - double tmp = inRangeStarParam; - inRangeStarParam = inRangeEndParam; - inRangeEndParam = tmp; + (inRangeStartParam, inRangeEndParam) = (inRangeEndParam, inRangeStartParam); } + // If start param is negative, we will reset it to 0 and shift the end accordingly - if (inRangeStarParam < 0) - { - double parRange = inRangeEndParam - inRangeStarParam; - inRangeStarParam = 0.0; - inRangeEndParam = parRange; - } + inRangeEndParam -= inRangeStartParam; endParam = UnitUtil.ScaleAngle(inRangeEndParam); - //endParam = UnitUtil.ScaleAngle(MathUtil.PutInRange(directrix.GetEndParameter(1), Math.PI, 2 * Math.PI) - - // MathUtil.PutInRange(originalStartParam, Math.PI, 2 * Math.PI)); } else + { endParam = 2.0 * Math.PI; + } } // Start creating IFC entities. @@ -403,9 +400,8 @@ private static void CreateAxisAndProfileCurveLCS(Curve directrix, double param, if (IFCAnyHandleUtil.IsNullOrHasNoValue(sweptArea)) return simpleSweptSolidHnd; - IFCAnyHandle curveHandle = null; IFCAnyHandle referenceSurfaceHandle = ExtrusionExporter.CreateSurfaceOfLinearExtrusionFromCurve(exporterIFC, directrix, axisLCS, 1.0, 1.0, - out curveHandle); + out IFCAnyHandle curveHandle); // Should this be moved up? Check. XYZ scaledOrigin = ExporterIFCUtils.TransformAndScalePoint(exporterIFC, axisLCS.Origin); @@ -421,12 +417,12 @@ private static void CreateAxisAndProfileCurveLCS(Curve directrix, double param, return simpleSweptSolidHnd; } - private static IList CreateRoughParametricTessellation(Curve curve) + private static IList CreateParametricTessellation(Curve curve, bool isCoarse) { IList originalTessellation = curve.Tessellate(); int numPoints = originalTessellation.Count; - int numTargetPoints = Math.Min(numPoints, 12); + int numTargetPoints = isCoarse ? Math.Min(numPoints, 12) : numPoints; int numInteriorPoints = numTargetPoints - 2; IList roughTessellation = new List(numTargetPoints); @@ -479,20 +475,20 @@ private static void AddScaledPointToList(ExporterIFC exporterIFC, IList lis /// Creates a facetation of a simple swept solid from a list of curve loops. /// /// The exporter. - /// The profile name. /// The profile curve loops. /// The normal of the plane that the path lies on. /// The path curve. + /// If true, create a coarse approximation of the directrix. /// The list of facet handles. - public static HashSet CreateSimpleSweptSolidAsBRep(ExporterIFC exporterIFC, string profileName, IList profileCurveLoops, - XYZ normal, Curve directrix) + public static HashSet CreateSimpleSweptSolidAsBRep(ExporterIFC exporterIFC, IList profileCurveLoops, + Curve directrix, bool isCoarse) { // see definition of IfcSurfaceCurveSweptAreaSolid from // http://www.buildingsmart-tech.org/ifc/IFC2x4/rc4/html/schema/ifcgeometricmodelresource/lexical/ifcsurfacecurvesweptareasolid.htm HashSet facetHnds = null; - if (!CanCreateSimpleSweptSolid(profileCurveLoops, normal, directrix)) + if (!CanCreateSimpleSweptSolid(profileCurveLoops, directrix)) return facetHnds; // An extra requirement, as we can't tessellate an unbound curve. @@ -557,7 +553,7 @@ private static void AddScaledPointToList(ExporterIFC exporterIFC, IList lis // Tessellate the Directrix. This only works for bound Directrix curves. Unfortunately, we get XYZ values, which we will have to convert // back to parameter values to get the local transform. - IList tessellatedDirectrixParameters = CreateRoughParametricTessellation(directrix); + IList tessellatedDirectrixParameters = CreateParametricTessellation(directrix, isCoarse); // Create all of the other outlines by transformng the first tessellated outline to the current transform. Transform profilePlaneTrf = Transform.CreateTranslation(ExporterIFCUtils.TransformAndScalePoint(exporterIFC, profileLCS.Origin)); diff --git a/Source/Revit.IFC.Export/Exporter/TextNoteExporter.cs b/Source/Revit.IFC.Export/Exporter/TextNoteExporter.cs index b37a7654..8563f414 100644 --- a/Source/Revit.IFC.Export/Exporter/TextNoteExporter.cs +++ b/Source/Revit.IFC.Export/Exporter/TextNoteExporter.cs @@ -117,7 +117,7 @@ public static void Export(ExporterIFC exporterIFC, TextNote textNote, ProductWra HashSet bodyItems = new HashSet() { repItemHnd }; IFCAnyHandle context2d = ExporterCacheManager.Get2DContextHandle(IFCRepresentationIdentifier.Annotation); IFCAnyHandle bodyRepHnd = RepresentationUtil.CreateAnnotationSetRep(exporterIFC, - textNote, catId, context2d, bodyItems); + textNote, catId, context2d, bodyItems, false); if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRepHnd)) throw new Exception("Failed to create shape representation."); diff --git a/Source/Revit.IFC.Export/Exporter/WallExporter.cs b/Source/Revit.IFC.Export/Exporter/WallExporter.cs index 7a837fe8..df038d60 100644 --- a/Source/Revit.IFC.Export/Exporter/WallExporter.cs +++ b/Source/Revit.IFC.Export/Exporter/WallExporter.cs @@ -76,7 +76,7 @@ private static bool GetDifferenceFromWallJoins(Document doc, ElementId wallId, S if (solidMeshInfo.GetMeshes().Count != 0) return false; - IList solidInfos = solidMeshInfo.GetSolidInfos(); + IList solidInfos = solidMeshInfo.SolidInfoList; foreach (SolidInfo solidInfo in solidInfos) { try @@ -492,6 +492,12 @@ private static bool HasUnsupportedCutsWallSweeps(Wall wallElement, bool hasCutsW baseBodyItemHnd = null; bodyItemHnd = null; } + //If there is clipping right next to the opening it can cause incorrect geometry as far one clipping face will be missed. In this case, export wall it as BRep. + else if (wallHasOpening && hasClipping && IsOpeningsIntersectClippings(wallElement, openingDataList)) + { + tr.RollBack(); + return null; + } else tr.Commit(); } @@ -586,7 +592,7 @@ private static void GetSolidsAndMeshes(Document doc, ExporterIFC exporterIFC, Ge (range == null) ? GeometryUtil.GetSplitSolidMeshGeometry(geometryElement) : GeometryUtil.GetSplitClippedSolidMeshGeometry(geometryElement, range); - foreach (SolidInfo solidInfo in solidMeshInfo.GetSolidInfos()) + foreach (SolidInfo solidInfo in solidMeshInfo.SolidInfoList) { // Walls can have integral wall sweeps. These wall sweeps will be exported // separately by the WallSweep element itself. If we try to include the wall sweep @@ -618,7 +624,7 @@ private static IList GetSolidOfWallSweep(GeometryElement geometryElement, (range == null) ? GeometryUtil.GetSplitSolidMeshGeometry(geometryElement) : GeometryUtil.GetSplitClippedSolidMeshGeometry(geometryElement, range); - foreach (SolidInfo solidInfo in solidMeshInfo.GetSolidInfos()) + foreach (SolidInfo solidInfo in solidMeshInfo.SolidInfoList) { if (solidInfo.OwnerElement is WallSweep) solids.Add(solidInfo.Solid); @@ -733,13 +739,6 @@ private static bool HasUnsupportedStackWallOpenings(Wall wallElement) return (openingElements != null && openingElements.Count > 0); } - private static void ConditionallyAddRepresentation(bool condition, - IList representationList, IFCAnyHandle representation) - { - if (condition && !IFCAnyHandleUtil.IsNullOrHasNoValue(representation)) - representationList.Add(representation); - } - private static string CalculateElementGUID(Element element) { // The first part maintains GUID compatibility with previous versions, @@ -759,11 +758,8 @@ private static string CalculateElementGUID(Element element) Element element, Wall wallElement, out string ifcEnumType) { IFCExportInfoPair exportType = ExporterUtil.GetProductExportType(exporterIFC, element, out ifcEnumType); - IFCExportInfoPair genericExportType = new IFCExportInfoPair(exportType.ExportInstance, exportType.ExportType, ifcEnumType); - - genericExportType.SetValueWithPair(exportType.ExportInstance, ifcEnumType); - if (wallElement != null && ExporterUtil.IsNotDefined(ifcEnumType) + if (wallElement != null && exportType.IsPredefinedTypeDefault && (exportType.ExportInstance == IFCEntityType.IfcWall || exportType.ExportInstance == IFCEntityType.IfcWallStandardCase)) { WallType wallType = wallElement.WallType; @@ -831,14 +827,14 @@ private static string CalculateElementGUID(Element element) bool exportByComponents = false; bool exportParts = false; bool setMaterialNameToPartName = false; - MaterialLayerSetInfo layersetInfo = new MaterialLayerSetInfo(exporterIFC, element, origWrapper); + MaterialLayerSetInfo layersetInfo = new MaterialLayerSetInfo(exporterIFC, element, origWrapper, geometryElement); // For IFC4RV export, wall will be split into its parts(temporarily) in order to export the wall by its parts // If Parts are created by code and not by user then their name should be equal to Material name. if (exportingWallElement) // If it is not Wall, e.g. FamilyInstance, skip split to Parts as this may cause problem later { setMaterialNameToPartName = ExporterUtil.CreateParts(element, layersetInfo.MaterialIds.Count, ref geometryElement); - ExporterUtil.ExportPartAs exportPartAs = ExporterUtil.CanExportByComponentsOrParts(element); + ExporterUtil.ExportPartAs exportPartAs = ExporterUtil.CanExportByComponentsOrParts(element, ref geometryElement); exportByComponents = (exportPartAs == ExporterUtil.ExportPartAs.ShapeAspect) && exportingWallElement; exportParts = exportPartAs == ExporterUtil.ExportPartAs.Part; } @@ -856,16 +852,10 @@ private static string CalculateElementGUID(Element element) if (!exportParts) { if (!(element is FamilyInstance)) - { + { // For IFC4 RV, only collect the solid and mesh here. Split Wall will be handled when processing individual parts later - if (exportByComponents) - { - GetSolidsAndMeshes(element.Document, exporterIFC, geometryElement, null, ref solids, ref meshes, out hasCutsWallSweep); - } - else - { - GetSolidsAndMeshes(element.Document, exporterIFC, geometryElement, range, ref solids, ref meshes, out hasCutsWallSweep); - } + GetSolidsAndMeshes(element.Document, exporterIFC, geometryElement, exportByComponents ? null : range, + ref solids, ref meshes, out hasCutsWallSweep); if (solids.Count == 0 && meshes.Count == 0) return null; } @@ -883,6 +873,7 @@ private static string CalculateElementGUID(Element element) exportingInplaceOpenings = false; geomElemToUse = geometryElement; } + Transform trf = Transform.Identity; if (geomElemToUse != geometryElement) trf = famInstWallElem.GetTransform(); @@ -941,8 +932,7 @@ private static string CalculateElementGUID(Element element) if (baseLevelId != ElementId.InvalidElementId) { Element baseLevel = doc.GetElement(baseLevelId); - if (baseLevel is Level) - baseWallElevation = (baseLevel as Level).Elevation; + baseWallElevation = (baseLevel as Level)?.Elevation ?? 0.0; } IFCAnyHandle axisRep = null; @@ -955,10 +945,10 @@ private static string CalculateElementGUID(Element element) bool exportedBodyDirectly = false; Curve centerCurve = GetWallAxis(wallElement); - XYZ localXDir = new XYZ(1, 0, 0); - XYZ localYDir = new XYZ(0, 1, 0); - XYZ localZDir = new XYZ(0, 0, 1); - XYZ localOrig = new XYZ(0, 0, 0); + XYZ localXDir = XYZ.BasisX; + XYZ localYDir = XYZ.BasisY; + XYZ localZDir = XYZ.BasisZ; + XYZ localOrig = XYZ.Zero; double eps = MathUtil.Eps(); if (centerCurve != null) @@ -1075,14 +1065,13 @@ private static string CalculateElementGUID(Element element) { string identifierOpt = "Axis"; // IFC2x2 convention string representationTypeOpt = null; - + HashSet axisItemSet = new HashSet(); if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView) { - IFCAnyHandle axisHandle = GeometryUtil.CreatePolyCurveFromCurve(exporterIFC, trimmedCurve); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(axisHandle)) - axisItemSet.Add(axisHandle); + axisItemSet.AddIfNotNull(GeometryUtil.CreatePolyCurveFromCurve( + exporterIFC, trimmedCurve)); representationTypeOpt = "Curve3D"; // We use Curve3D for IFC4RV } else @@ -1092,10 +1081,9 @@ private static string CalculateElementGUID(Element element) IList tmpAxisHandles = info.GetCurves(); foreach (IFCAnyHandle axisHandle in tmpAxisHandles) { - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(axisHandle)) + if (axisItemSet.AddIfNotNull(axisHandle)) { // We will only export the first curve as the axis. - axisItemSet.Add(axisHandle); break; } } @@ -1109,41 +1097,62 @@ private static string CalculateElementGUID(Element element) IFCAnyHandle contextOfItemsAxis = ExporterCacheManager.Get3DContextHandle(IFCRepresentationIdentifier.Axis); axisRep = RepresentationUtil.CreateShapeRepresentation(exporterIFC, element, catId, contextOfItemsAxis, identifierOpt, representationTypeOpt, axisItemSet); - - // If it is export by components, there will be no body at this step, the exportedAsWallWithAxis will be set to true here - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(axisRep) && exportByComponents) - exportedAsWallWithAxis = true; } } } - exportType = CalculateExportType(exporterIFC, element, wallElement, out ifcEnumType); - - IList cutPairOpenings = new List(); - // We only try to export by extrusion using this function if: - // 1. We aren't trying to create parts or components. - // 2. We have a native Revit wall whose non-trimmed axis we are exporting. - // 3. We don't have a wall that's part of a stacked wall, if the stacked wall has openings. - // Any of the cases above could mean that the internal API function would return - // incorrect results (generally, missing openings or clippings). - - if (CanTryToCreateAsExtrusion(wallElement, exportParts, exportByComponents, exportingWallElement, - exportingAxis, trimmedCurve, isCurtainPanel, hasCutsWallSweep)) + // We try this first because it can fail. If it does, we revert to standard export. + using (IFCExportBodyParams extraParams = new IFCExportBodyParams()) { - bool isCompletelyClipped; - bodyRep = TryToCreateAsExtrusion(exporterIFC, wallElement, exportType, - connectedWalls, solids, meshes, baseWallElevation, catId, - centerCurve, trimmedCurve, orientationTrf, depth, zSpan, range, setter, - out cutPairOpenings, out isCompletelyClipped, out scaledFootprintArea, out scaledLength); - if (isCompletelyClipped) - return null; + IFCExportBodyParams partECData = null; + IFCAnyHandle prodRep = null; + IFCAnyHandle hostShapeRepFromPartsList = null; + + if (!exportParts && exportByComponents) + { + partECData = new IFCExportBodyParams(); + hostShapeRepFromPartsList = PartExporter.ExportHostPartAsShapeAspects(exporterIFC, + element, prodRep, localWrapper, setter, localPlacement, overrideLevelId, layersetInfo, + partECData, solidsOfWallSweep); + if (IFCAnyHandleUtil.IsNullOrHasNoValue(hostShapeRepFromPartsList)) + { + partECData.ClearOpenings(); + extraParams.ClearOpenings(); + exportByComponents = false; + } + } - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep)) + // If it is export by components, there will be no body at this step, the exportedAsWallWithAxis will be set to true here + if (exportByComponents && !IFCAnyHandleUtil.IsNullOrHasNoValue(axisRep)) + { exportedAsWallWithAxis = true; - } + } + + exportType = CalculateExportType(exporterIFC, element, wallElement, out ifcEnumType); + + IList cutPairOpenings = new List(); + // We only try to export by extrusion using this function if: + // 1. We aren't trying to create parts or components. + // 2. We have a native Revit wall whose non-trimmed axis we are exporting. + // 3. We don't have a wall that's part of a stacked wall, if the stacked wall has openings. + // Any of the cases above could mean that the internal API function would return + // incorrect results (generally, missing openings or clippings). + + if (CanTryToCreateAsExtrusion(wallElement, exportParts, exportByComponents, exportingWallElement, + exportingAxis, trimmedCurve, isCurtainPanel, hasCutsWallSweep)) + { + bool isCompletelyClipped; + bodyRep = TryToCreateAsExtrusion(exporterIFC, wallElement, exportType, + connectedWalls, solids, meshes, baseWallElevation, catId, + centerCurve, trimmedCurve, orientationTrf, depth, zSpan, range, setter, + out cutPairOpenings, out isCompletelyClipped, out scaledFootprintArea, out scaledLength); + if (isCompletelyClipped) + return null; + + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep)) + exportedAsWallWithAxis = true; + } - using (IFCExportBodyParams extraParams = new IFCExportBodyParams()) - { BodyData bodyData = null; // If it is not a Wall object (FamilyInstance) then this part needs to run even for IFC4RV @@ -1207,19 +1216,24 @@ private static string CalculateElementGUID(Element element) } } - IFCAnyHandle prodRep = null; if (!exportParts) { IList representations = new List(); - ConditionallyAddRepresentation(exportingAxis, representations, axisRep); - ConditionallyAddRepresentation(true, representations, bodyRep); - + if (exportingAxis) + representations.AddIfNotNull(axisRep); + //If at this step we do not have a body representation, it is possible that + //the body representation was created during PartExporter.ExportHostPartAsShapeAspects execution. + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep)) + representations.Add(bodyRep); + else + representations.AddIfNotNull(hostShapeRepFromPartsList); + IFCAnyHandle boundingBoxRep = null; if ((solids.Count > 0) || (meshes.Count > 0)) boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, solids, meshes, Transform.Identity); else boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geometryElement, Transform.Identity); - ConditionallyAddRepresentation(true, representations, boundingBoxRep); + representations.AddIfNotNull(boundingBoxRep); prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations); } @@ -1229,13 +1243,13 @@ private static string CalculateElementGUID(Element element) IFCAnyHandle wallHnd = null; string elemGUID = CalculateElementGUID(element); - + if (exportedAsWallWithAxis && CanExportAsWallStandardCase(wallElement, exportParts) && (exportType.ExportInstance == IFCEntityType.IfcWall || exportType.ExportInstance == IFCEntityType.IfcWallStandardCase)) { wallHnd = IFCInstanceExporter.CreateWallStandardCase(exporterIFC, element, elemGUID, ownerHistory, localPlacement, prodRep, ifcEnumType); - exportType.SetValueWithPair(IFCEntityType.IfcWallStandardCase, ifcEnumType); + exportType.SetByTypeAndPredefinedType(IFCEntityType.IfcWallStandardCase, ifcEnumType); } else { @@ -1244,25 +1258,14 @@ private static string CalculateElementGUID(Element element) } if (exportParts && !exportByComponents) + { PartExporter.ExportHostPart(exporterIFC, element, wallHnd, localWrapper, setter, localPlacement, overrideLevelId, setMaterialNameToPartName); + } else if (exportByComponents) { - using (IFCExportBodyParams partECData = new IFCExportBodyParams()) - { - IFCAnyHandle hostShapeRepFromPartsList = PartExporter.ExportHostPartAsShapeAspects(exporterIFC, element, prodRep, - localWrapper, setter, localPlacement, overrideLevelId, layersetInfo, partECData, solidsOfWallSweep); - if (IFCAnyHandleUtil.IsNullOrHasNoValue(hostShapeRepFromPartsList)) - { - partECData.ClearOpenings(); - extraParams.ClearOpenings(); - // Delete Wall handle when there is no representation from the parts and return null - IFCAnyHandleUtil.Delete(wallHnd); - return null; - } - - Transform offsetTransform = (bodyData != null) ? bodyData.OffsetTransform : Transform.Identity; - OpeningUtil.CreateOpeningsIfNecessary(wallHnd, element, partECData, offsetTransform, exporterIFC, localPlacement, setter, localWrapper); - } + // We can only associate the openings with the wall after the wall handle has been created. + Transform offsetTransform = (bodyData != null) ? bodyData.OffsetTransform : Transform.Identity; + OpeningUtil.CreateOpeningsIfNecessary(wallHnd, element, partECData, offsetTransform, exporterIFC, localPlacement, setter, localWrapper); } localWrapper.AddElement(element, wallHnd, setter, extraParams, true, exportType); @@ -1297,7 +1300,7 @@ private static string CalculateElementGUID(Element element) scaledLength = MathUtil.IsAlmostZero(scaledLength) ? extraParams.ScaledLength : scaledLength; if (exportByComponents && layersetInfo != null) { - PropertyUtil.CreateWallBaseQuantities(exporterIFC, wallElement, solids, meshes, wallHnd, scaledLength, depth, + PropertyUtil.CreateWallBaseQuantities(exporterIFC, wallElement, solids, meshes, wallHnd, scaledLength, depth, scaledFootprintArea, extraParams, layersetInfo.LayerQuantityWidthHnd); } else @@ -1307,7 +1310,7 @@ private static string CalculateElementGUID(Element element) } } else - { + { if (!exportParts) { // Only export one material for 2x2; for future versions, export the whole list. @@ -1338,7 +1341,7 @@ private static string CalculateElementGUID(Element element) scaledLength = MathUtil.IsAlmostZero(scaledLength) ? extraParams.ScaledLength : scaledLength; if (layersetInfo != null) { - PropertyUtil.CreateWallBaseQuantities(exporterIFC, wallElement, solids, meshes, wallHnd, scaledLength, depth, + PropertyUtil.CreateWallBaseQuantities(exporterIFC, wallElement, solids, meshes, wallHnd, scaledLength, depth, scaledFootprintArea, extraParams, layersetInfo.LayerQuantityWidthHnd); } else @@ -1355,7 +1358,7 @@ private static string CalculateElementGUID(Element element) HostObject hostObject = element as HostObject; if (!ExporterCacheManager.ExportOptionsCache.ExportAs2x2 || exportedAsWallWithAxis) HostObjectExporter.ExportHostObjectMaterials(exporterIFC, hostObject, localWrapper.GetAnElement(), - geometryElement, localWrapper, wallLevelId, Toolkit.IFCLayerSetDirection.Axis2, !exportedAsWallWithAxis, null); + geometryElement, localWrapper, wallLevelId, Toolkit.IFCLayerSetDirection.Axis2, !exportedAsWallWithAxis, null, layersetInfo); } ExportGenericType(exporterIFC, localWrapper, wallHnd, element, matId, ifcEnumType); @@ -1391,7 +1394,7 @@ private static string CalculateElementGUID(Element element) // We will not split walls and columns if the assemblyId is set, as we would like to keep the original wall // associated with the assembly, on the level of the assembly. - bool splitWall = ExporterCacheManager.ExportOptionsCache.WallAndColumnSplitting && (element.AssemblyInstanceId == ElementId.InvalidElementId); + bool splitWall = ExporterCacheManager.ExportOptionsCache.WallAndColumnSplitting && !ExporterUtil.IsContainedInAssembly(element); if (splitWall) { IList levels = new List(); @@ -1405,9 +1408,9 @@ private static string CalculateElementGUID(Element element) int numPartsToExport = ranges.Count; if (numPartsToExport == 0) { - IFCAnyHandle wallElemHnd = ExportWallBase(exporterIFC, ifcEnumType, element, connectedWalls, ref geometryElement, productWrapper, ElementId.InvalidElementId, null); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(wallElemHnd)) - createdWalls.Add(wallElemHnd); + createdWalls.AddIfNotNull(ExportWallBase(exporterIFC, ifcEnumType, element, + connectedWalls, ref geometryElement, productWrapper, + ElementId.InvalidElementId, null)); } else { @@ -1416,9 +1419,9 @@ private static string CalculateElementGUID(Element element) for (int ii = 0; ii < numPartsToExport; ii++) { rangeSetter.IncreaseRangeIndex(); - IFCAnyHandle wallElemHnd = ExportWallBase(exporterIFC, ifcEnumType, element, connectedWalls, ref geometryElement, productWrapper, levels[ii], ranges[ii]); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(wallElemHnd)) - createdWalls.Add(wallElemHnd); + createdWalls.AddIfNotNull(ExportWallBase(exporterIFC, ifcEnumType, + element, connectedWalls, ref geometryElement, productWrapper, + levels[ii], ranges[ii])); } } } @@ -1431,9 +1434,8 @@ private static string CalculateElementGUID(Element element) foreach (KeyValuePair levelRange in levelRangeList) { rangeSetter.IncreaseRangeIndex(); - IFCAnyHandle wallElemHnd = ExportDummyWall(exporterIFC, element, geometryElement, productWrapper, levelRange.Key, levelRange.Value); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(wallElemHnd)) - createdWalls.Add(wallElemHnd); + createdWalls.AddIfNotNull(ExportDummyWall(exporterIFC, element, + geometryElement, productWrapper, levelRange.Key, levelRange.Value)); } } } @@ -1463,7 +1465,9 @@ public static void Export(ExporterIFC exporterIFC, Wall wallElement, ref Geometr // We originally skipped exporting the wall only if the containing curtain wall was also exported. // However, if the container isn't being exported, the panel shouldn't be either. if ((container is Wall) && ((container as Wall).CurtainGrid != null)) + { return; + } } } @@ -1475,14 +1479,20 @@ public static void Export(ExporterIFC exporterIFC, Wall wallElement, ref Geometr // We skip over the "stacked wall" but the invidual walls inside that stacked wall will still be exported. if (wallTypeKind == WallKind.Stacked) + { return; + } - IList> connectedWalls = new List>(2); - connectedWalls.Add(ExporterIFCUtils.GetConnectedWalls(wallElement, IFCConnectedWallDataLocation.Start)); - connectedWalls.Add(ExporterIFCUtils.GetConnectedWalls(wallElement, IFCConnectedWallDataLocation.End)); + IList> connectedWalls = new List> + { + ExporterIFCUtils.GetConnectedWalls(wallElement, IFCConnectedWallDataLocation.Start), + ExporterIFCUtils.GetConnectedWalls(wallElement, IFCConnectedWallDataLocation.End) + }; if (CurtainSystemExporter.IsCurtainSystem(wallElement)) + { CurtainSystemExporter.ExportWall(exporterIFC, wallElement, productWrapper); + } else { // ExportWall may decide to export as an IfcFooting for some retaining and foundation walls. @@ -1628,7 +1638,7 @@ public static void Export(ExporterIFC exporterIFC, Wall wallElement, ref Geometr return; IFCExportInfoPair exportType = ExporterUtil.GetProductExportType(exporterIFC, element, out _); - exportType.ValidatedPredefinedType = ifcTypeEnum; + exportType.PredefinedType = ifcTypeEnum; IFCAnyHandle wallType = ExporterCacheManager.ElementTypeToHandleCache.Find(elementType, exportType); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(wallType)) @@ -1638,8 +1648,7 @@ public static void Export(ExporterIFC exporterIFC, Wall wallElement, ref Geometr } string guid = GUIDUtil.GenerateIFCGuidFrom(elementType, exportType); - wallType = FamilyExporterUtil.ExportGenericType(exporterIFC, exportType, - exportType.ValidatedPredefinedType, null, null, element, elementType, guid); + wallType = FamilyExporterUtil.ExportGenericType(exporterIFC, exportType, null, null, element, elementType, guid); wrapper.RegisterHandleWithElementType(elementType, exportType, wallType, null); @@ -1888,6 +1897,64 @@ static bool IsConnectedWithNonVerticalWall(IList> co return false; } + /// + /// Identifies if any of the wall openings intersect with the floor clippings. + /// + /// The wall element. + /// The wall openings data. + /// Returns true if any of wall openings intersect with floor clippings + static bool IsOpeningsIntersectClippings(Wall wallElement, IList openingDataList) + { + Document doc = wallElement.Document; + ICollection joinedElements = JoinGeometryUtils.GetJoinedElements(doc, wallElement); + + foreach (IFCOpeningData openingData in openingDataList) + { + ElementId openingId = openingData.OpeningElementId; + Element openingElement = doc.GetElement(openingId); + if (openingElement == null) + continue; + + GeometryElement openingGeometry = openingElement.get_Geometry(new Options()); + if (openingGeometry == null) + continue; + + SolidMeshGeometryInfo openingSolidMeshInfo = GeometryUtil.GetSplitSolidMeshGeometry(openingGeometry); + foreach (ElementId joinedElementId in joinedElements) + { + Element joinedElement = doc.GetElement(joinedElementId); + if (joinedElement == null || !(joinedElement is Floor)) + continue; + + GeometryElement joinedElementGeometry = joinedElement.get_Geometry(new Options()); + if (joinedElementGeometry == null) + continue; + + SolidMeshGeometryInfo joinedElementSolidMeshInfo = GeometryUtil.GetSplitSolidMeshGeometry(openingGeometry); + + foreach (SolidInfo openingSolidInfo in openingSolidMeshInfo.SolidInfoList) + { + foreach (SolidInfo joinedElementSolidInfo in joinedElementSolidMeshInfo.SolidInfoList) + { + try + { + BooleanOperationsUtils.ExecuteBooleanOperationModifyingOriginalSolid(openingSolidInfo.Solid, + joinedElementSolidInfo.Solid, BooleanOperationsType.Intersect); + } + catch + { + continue; + } + + return true; + } + } + } + } + + return false; + } + /// /// Gets the curve loop(s) that represent the bottom or top face of the wall. /// @@ -1963,4 +2030,4 @@ static IFCConnectionType GetIFCConnectionTypeFromLocation(IFCConnectedWallDataLo } } } -} \ No newline at end of file +} diff --git a/Source/Revit.IFC.Export/Exporter/WallSweepExporter.cs b/Source/Revit.IFC.Export/Exporter/WallSweepExporter.cs index 4f5ef559..64b75a6d 100644 --- a/Source/Revit.IFC.Export/Exporter/WallSweepExporter.cs +++ b/Source/Revit.IFC.Export/Exporter/WallSweepExporter.cs @@ -50,8 +50,8 @@ public static void Export(ExporterIFC exporterIFC, WallSweep wallSweep, Geometry return; HostObjectExporter.ExportHostObjectMaterials(exporterIFC, wallSweep, productWrapper.GetAnElement(), - geometryElement, productWrapper, - ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis2, null, null); + geometryElement, productWrapper, + ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis2, null, null); } } } diff --git a/Source/Revit.IFC.Export/Exporter/ZoneInfo.cs b/Source/Revit.IFC.Export/Exporter/ZoneInfo.cs index 0f1f804d..372c7883 100644 --- a/Source/Revit.IFC.Export/Exporter/ZoneInfo.cs +++ b/Source/Revit.IFC.Export/Exporter/ZoneInfo.cs @@ -19,6 +19,7 @@ using System; using System.Collections.Generic; +using System.Linq; using Autodesk.Revit.DB; using Autodesk.Revit.DB.IFC; using Revit.IFC.Common.Utility; @@ -70,7 +71,7 @@ void InitBasePropZoneLabels() } } - private int CurrentZoneNumber { get; set; } = 1; + public int CurrentZoneNumber { get; private set; } = 1; private void SetPropZoneLabels() { @@ -182,9 +183,7 @@ public class ZoneInfo /// /// Container with string information. /// The room handle for this zone. - /// The Pset_ZoneCommon handle for this zone. - public ZoneInfo(ZoneInfoFinder zoneInfoFinder, IFCAnyHandle roomHandle, - IFCAnyHandle zoneCommonPSetHandle) + public ZoneInfo(ZoneInfoFinder zoneInfoFinder, IFCAnyHandle roomHandle) { if (zoneInfoFinder != null) { @@ -195,7 +194,6 @@ public class ZoneInfo } RoomHandles.Add(roomHandle); - ZoneCommonProperySetHandle = zoneCommonPSetHandle; } /// @@ -222,22 +220,17 @@ public void UpdateZoneInfo(ZoneInfoFinder zoneInfoFinder) if (zoneInfoFinder == null) return; - string newObjectType = zoneInfoFinder.GetPropZoneValue(ZoneInfoLabel.ObjectType); - string newDescription = zoneInfoFinder.GetPropZoneValue(ZoneInfoLabel.Description); - string newLongName = zoneInfoFinder.GetPropZoneValue(ZoneInfoLabel.LongName); - string newGroupName = zoneInfoFinder.GetPropZoneValue(ZoneInfoLabel.GroupName); - if (string.IsNullOrEmpty(ObjectType)) - ObjectType = newObjectType; + ObjectType = zoneInfoFinder.GetPropZoneValue(ZoneInfoLabel.ObjectType); if (string.IsNullOrEmpty(Description)) - Description = newDescription; + Description = zoneInfoFinder.GetPropZoneValue(ZoneInfoLabel.Description); if (string.IsNullOrEmpty(LongName)) - LongName = newLongName; + LongName = zoneInfoFinder.GetPropZoneValue(ZoneInfoLabel.LongName); if (string.IsNullOrEmpty(GroupName)) - GroupName = newGroupName; + GroupName = zoneInfoFinder.GetPropZoneValue(ZoneInfoLabel.GroupName); } /// @@ -285,6 +278,152 @@ public void ConditionalAddClassification(IFCFile file, string zoneClassification ExporterCacheManager.ClassificationCache.FindOrCreateClassificationReference(file, key); } + static private IFCAnyHandle CreateLabelPropertyFromPattern(string[] patterns, string basePropertyName, + IFCFile file, Element element) + { + foreach (string pattern in patterns) + { + string propertyName = string.Format(pattern, basePropertyName); + IFCAnyHandle propSingleValue = PropertyUtil.CreateLabelPropertyFromElement(file, element, + propertyName, BuiltInParameter.INVALID, basePropertyName, PropertyValueType.SingleValue, + null); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propSingleValue)) + return propSingleValue; + } + return null; + } + + static private IFCAnyHandle CreateIdentifierPropertyFromPattern(string[] patterns, string basePropertyName, + IFCFile file, Element element) + { + foreach (string pattern in patterns) + { + string propertyName = string.Format(pattern, basePropertyName); + IFCAnyHandle propSingleValue = PropertyUtil.CreateIdentifierPropertyFromElement(file, + element, propertyName, BuiltInParameter.INVALID, basePropertyName, + PropertyValueType.SingleValue); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propSingleValue)) + return propSingleValue; + } + return null; + } + + static private IFCAnyHandle CreateAreaMeasurePropertyFromPattern(string[] patterns, string basePropertyName, + IFCFile file, Element element) + { + foreach (string pattern in patterns) + { + string propertyName = string.Format(pattern, basePropertyName); + IFCAnyHandle propSingleValue = PropertyUtil.CreateAreaPropertyFromElement(file, + element, propertyName, BuiltInParameter.INVALID, basePropertyName, + PropertyValueType.SingleValue); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propSingleValue)) + return propSingleValue; + } + return null; + } + + static private IFCAnyHandle CreateBooleanPropertyFromPattern(string[] patterns, string basePropertyName, + IFCFile file, Element element) + { + foreach (string pattern in patterns) + { + string propertyName = string.Format(pattern, basePropertyName); + IFCAnyHandle propSingleValue = PropertyUtil.CreateBooleanPropertyFromElement(file, element, + propertyName, basePropertyName, PropertyValueType.SingleValue); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propSingleValue)) + return propSingleValue; + } + return null; + } + + /// + /// Get the name of the net planned area property, depending on the current schema, for levels and zones. + /// + /// The name of the net planned area property. + /// Note that PSet_SpaceCommon has had the property "NetPlannedArea" since IFC2x3. + static private string GetLevelAndZoneNetPlannedAreaName() + { + return ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4 ? "NetAreaPlanned" : "NetPlannedArea"; + } + + /// + /// Get the name of the gross planned area property, depending on the current schema, for levels and zones. + /// + /// The name of the net planned area property. + /// Note that PSet_SpaceCommon has had the property "GrossPlannedArea" since IFC2x3. + static private string GetLevelAndZoneGrossPlannedAreaName() + { + return ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4 ? "GrossAreaPlanned" : "GrossPlannedArea"; + } + + /// + /// Collect the information needed to create PSet_ZoneCommon. + /// + /// The IFC file. + /// The Revit element. + /// The index of the zone for the current space. + public void CollectZoneCommonPSetData(IFCFile file, Element element, int index) + { + // We don't use the generic Property Set mechanism because Zones aren't "real" elements. + string indexString = (index > 1) ? index.ToString() : string.Empty; + const string basePSetName = "Pset_ZoneCommon"; + + string[] patterns = new string[2] { + basePSetName + indexString + ".{0}", + "Zone" + "{0}" + indexString + }; + + ZoneCommonHandles.AddIfNotNullAndNewKey("Category", + CreateLabelPropertyFromPattern(patterns, "Category", file, element)); + + string grossPlannedAreaName = GetLevelAndZoneGrossPlannedAreaName(); + ZoneCommonHandles.AddIfNotNullAndNewKey(grossPlannedAreaName, + CreateAreaMeasurePropertyFromPattern(patterns, grossPlannedAreaName, file, + element)); + + string netPlannedAreaName = GetLevelAndZoneNetPlannedAreaName(); + ZoneCommonHandles.AddIfNotNullAndNewKey(netPlannedAreaName, + CreateAreaMeasurePropertyFromPattern(patterns, netPlannedAreaName, file, element)); + + ZoneCommonHandles.AddIfNotNullAndNewKey("PubliclyAccessible", + CreateBooleanPropertyFromPattern(patterns, "PubliclyAccessible", file, element)); + + ZoneCommonHandles.AddIfNotNullAndNewKey("HandicapAccessible", + CreateBooleanPropertyFromPattern(patterns, "HandicapAccessible", file, element)); + + ZoneCommonHandles.AddIfNotNullAndNewKey("IsExternal", + CreateBooleanPropertyFromPattern(patterns, "IsExternal", file, element)); + + if (ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4x3) + { + ZoneCommonHandles.AddIfNotNullAndNewKey("Reference", + CreateIdentifierPropertyFromPattern(patterns, "Reference", file, element)); + } + + if (ZoneCommonHandles.Count > 0 && ZoneCommonGUID == null) + { + string psetName = basePSetName + indexString; + ZoneCommonGUID = GUIDUtil.GenerateIFCGuidFrom( + GUIDUtil.CreateGUIDString(element, psetName)); + } + } + + /// + /// Create the PSet_ZoneCommon property set, if applicable. + /// + /// The IFCFile parameter. + /// The handle to the PSet_ZoneCommon property set, if created. + public IFCAnyHandle CreateZoneCommonPSetData(IFCFile file) + { + if (ZoneCommonHandles.Count == 0 || ZoneCommonGUID == null) + return null; + + return IFCInstanceExporter.CreatePropertySet(file, ZoneCommonGUID, + ExporterCacheManager.OwnerHistoryHandle, "PSet_ZoneCommon", null, + ZoneCommonHandles.Values.ToHashSet()); + } + /// /// The long name, for IFC4+. /// @@ -301,9 +440,12 @@ public void ConditionalAddClassification(IFCFile file, string zoneClassification public IDictionary ClassificationReferences { get; set; } = new Dictionary(); + public IDictionary ZoneCommonHandles { get; set; } = + new Dictionary(); + /// - /// The associated Pset_ZoneCommon handle, if any. + /// The GUID for the Pset_ZoneCommon. /// - public IFCAnyHandle ZoneCommonProperySetHandle { get; set; } = null; + public string ZoneCommonGUID { get; private set; } = null; } } \ No newline at end of file diff --git a/Source/Revit.IFC.Export/Properties/AssemblyInfo.cs b/Source/Revit.IFC.Export/Properties/AssemblyInfo.cs index 3c41c267..18a06945 100644 --- a/Source/Revit.IFC.Export/Properties/AssemblyInfo.cs +++ b/Source/Revit.IFC.Export/Properties/AssemblyInfo.cs @@ -1,7 +1,6 @@ using System.Reflection; #region Using directives -#if IFC_OPENSOURCE // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. @@ -10,17 +9,14 @@ [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Autodesk")] [assembly: AssemblyProduct("IFC Exporter for Revit")] -[assembly: AssemblyCopyright("© 2012-2023 Autodesk, Inc. All rights reserved.")] +[assembly: AssemblyCopyright("© 2012-2024 Autodesk, Inc. All rights reserved.")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -[assembly: AssemblyVersion("24.2.0.49")] -[assembly: AssemblyFileVersion("24.2.0.49")] - -#endif +[assembly: AssemblyVersion("25.2.0.5")] +[assembly: AssemblyFileVersion("25.2.0.5")] // Version information can now be found in Source\Foundation\RevitENU\Version.cs // #endregion - diff --git a/Source/Revit.IFC.Export/Properties/Resources.Designer.cs b/Source/Revit.IFC.Export/Properties/Resources.Designer.cs index a5a45b5d..9496f017 100644 --- a/Source/Revit.IFC.Export/Properties/Resources.Designer.cs +++ b/Source/Revit.IFC.Export/Properties/Resources.Designer.cs @@ -19,7 +19,7 @@ namespace Revit.IFC.Export.Properties { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { diff --git a/Source/Revit.IFC.Export/Revit.IFC.Export.csproj b/Source/Revit.IFC.Export/Revit.IFC.Export.csproj index 251b1a8e..7994e715 100644 --- a/Source/Revit.IFC.Export/Revit.IFC.Export.csproj +++ b/Source/Revit.IFC.Export/Revit.IFC.Export.csproj @@ -1,356 +1,28 @@ - - + - Debug - x86 - 8.0.30703 - 2.0 - {BCE5141A-291B-4CD8-A69B-7B9345AA00E9} - Library - Properties Revit.IFC.Export Revit.IFC.Export - v4.8 - - - 512 - {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - 4 - Publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true - Revit.IFC - - - - - - false - x64 - bin\Debugx64\ - - - false - bin\Releasex64\ - x64 + True + + - - ..\..\..\..\Program Files\Autodesk\Revit 2024\RevitAPI.dll - - - ..\..\..\..\Program Files\Autodesk\Revit 2024\RevitAPIIFC.dll - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + True True Resources.resx - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - False - .NET Framework 2.0 %28x86%29 - false - - - False - .NET Framework 3.0 %28x86%29 - true - - - False - .NET Framework 3.5 - false - - - False - Windows Installer 3.1 - true - - {032EA4DC-181F-4453-9F93-E08DE1C07D95} - Revit.IFC.Common False + All + All @@ -364,40 +36,49 @@ MSBuild:Compile Revit.IFC.Export.Utility - PreserveNewest + True + True - - - 4.6.6 - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - 4.6.6 - - - 0.1.22 - - - 10.0.3 - - - - - xcopy "$(TargetPath)" "C:\ProgramData\Autodesk\ApplicationPlugins\IFC 2024.bundle\Contents\2024\" /F /R /Y /I -xcopy "$(TargetDir)GeometryGymIFC.dll" "C:\ProgramData\Autodesk\ApplicationPlugins\IFC 2024.bundle\Contents\2024\" /F /R /Y /I - - - \ No newline at end of file + + + + + + all + + + 4.6.6 + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + 4.6.6 + + + + + + ..\..\..\..\Program Files\Autodesk\Revit 2025\RevitAPI.dll + + + ..\..\..\..\Program Files\Autodesk\Revit 2025\RevitAPIIFC.dll + + + ..\..\..\..\Program Files\Autodesk\Revit 2025\RevitAPIUI.dll + + + diff --git a/Source/Revit.IFC.Export/Revit.IFC.Export.props b/Source/Revit.IFC.Export/Revit.IFC.Export.props deleted file mode 100644 index 0e84fc8e..00000000 --- a/Source/Revit.IFC.Export/Revit.IFC.Export.props +++ /dev/null @@ -1,25 +0,0 @@ - - - - bin\Debugx64\ - DEBUG;TRACE;IFC_OPENSOURCE - true - false - false - 4 - full - prompt - - - bin\Releasex64\ - TRACE;IFC_OPENSOURCE - false - true - false - 4 - none - prompt - - - - diff --git a/Source/Revit.IFC.Export/Toolkit/IFCDataUtil.cs b/Source/Revit.IFC.Export/Toolkit/IFCDataUtil.cs index 2f618231..75d3041f 100644 --- a/Source/Revit.IFC.Export/Toolkit/IFCDataUtil.cs +++ b/Source/Revit.IFC.Export/Toolkit/IFCDataUtil.cs @@ -142,7 +142,7 @@ public static IFCData CreateAsInteger(int value) /// The IFCData object. public static IFCData CreateAsReal(double value) { - return CreateAsMeasure(value, "IfcReal"); + return CreateAsMeasureWithUnit(value, "IfcReal"); } /// @@ -152,7 +152,7 @@ public static IFCData CreateAsReal(double value) /// The IFCData object. public static IFCData CreateAsNumeric(double value) { - return CreateAsMeasure(value, "IfcNumericMeasure"); + return CreateAsMeasureWithUnit(value, "IfcNumericMeasure"); } /// @@ -162,7 +162,7 @@ public static IFCData CreateAsNumeric(double value) /// The IFCData object. public static IFCData CreateAsRatioMeasure(double value) { - return CreateAsMeasure(value, "IfcRatioMeasure"); + return CreateAsMeasureWithUnit(value, "IfcRatioMeasure"); } /// @@ -172,7 +172,7 @@ public static IFCData CreateAsRatioMeasure(double value) /// The IFCData object. public static IFCData CreateAsNormalisedRatioMeasure(double value) { - return CreateAsMeasure(value, "IfcNormalisedRatioMeasure"); + return CreateAsMeasureWithUnit(value, "IfcNormalisedRatioMeasure"); } /// @@ -182,7 +182,7 @@ public static IFCData CreateAsNormalisedRatioMeasure(double value) /// The IFCData object. public static IFCData CreateAsSpecularExponent(double value) { - return CreateAsMeasure(value, "IfcSpecularExponent"); + return CreateAsMeasureWithUnit(value, "IfcSpecularExponent"); } /// @@ -192,7 +192,7 @@ public static IFCData CreateAsSpecularExponent(double value) /// The IFCData object. public static IFCData CreateAsPositiveRatioMeasure(double value) { - return CreateAsMeasure(value, "IfcPositiveRatioMeasure"); + return CreateAsMeasureWithUnit(value, "IfcPositiveRatioMeasure"); } /// @@ -202,7 +202,7 @@ public static IFCData CreateAsPositiveRatioMeasure(double value) /// The IFCData object. public static IFCData CreateAsLengthMeasure(double value) { - return CreateAsMeasure(value, "IfcLengthMeasure"); + return CreateAsMeasureWithUnit(value, "IfcLengthMeasure"); } /// @@ -212,7 +212,7 @@ public static IFCData CreateAsLengthMeasure(double value) /// The IFCData object. public static IFCData CreateAsVolumeMeasure(double value) { - return CreateAsMeasure(value, "IfcVolumeMeasure"); + return CreateAsMeasureWithUnit(value, "IfcVolumeMeasure"); } /// @@ -222,7 +222,10 @@ public static IFCData CreateAsVolumeMeasure(double value) /// The IFCData object. public static IFCData CreateAsPositiveLengthMeasure(double value) { - return CreateAsMeasure(value, "IfcPositiveLengthMeasure"); + if (value > MathUtil.Eps()) + return CreateAsMeasureWithUnit(value, "IfcPositiveLengthMeasure"); + else + return null; } /// @@ -232,7 +235,10 @@ public static IFCData CreateAsPositiveLengthMeasure(double value) /// The IFCData object. public static IFCData CreateAsPositivePlaneAngleMeasure(double value) { - return CreateAsMeasure(value, "IfcPositivePlaneAngleMeasure"); + if (value > MathUtil.Eps()) + return CreateAsMeasureWithUnit(value, "IfcPositivePlaneAngleMeasure"); + else + return null; } /// @@ -242,7 +248,7 @@ public static IFCData CreateAsPositivePlaneAngleMeasure(double value) /// The IFCData object. public static IFCData CreateAsPlaneAngleMeasure(double value) { - return CreateAsMeasure(value, "IfcPlaneAngleMeasure"); + return CreateAsMeasureWithUnit(value, "IfcPlaneAngleMeasure"); } /// @@ -252,7 +258,7 @@ public static IFCData CreateAsPlaneAngleMeasure(double value) /// The IFCData object. public static IFCData CreateAsAreaMeasure(double value) { - return CreateAsMeasure(value, "IfcAreaMeasure"); + return CreateAsMeasureWithUnit(value, "IfcAreaMeasure"); } /// @@ -262,7 +268,7 @@ public static IFCData CreateAsAreaMeasure(double value) /// The IFCData object. public static IFCData CreateAsAccelerationMeasure(double value) { - return CreateAsMeasure(value, "IfcAccelerationMeasure"); + return CreateAsMeasureWithUnit(value, "IfcAccelerationMeasure"); } /// @@ -272,7 +278,43 @@ public static IFCData CreateAsAccelerationMeasure(double value) /// The IFCData object. public static IFCData CreateAsEnergyMeasure(double value) { - return CreateAsMeasure(value, "IfcEnergyMeasure"); + return CreateAsMeasureWithUnit(value, "IfcEnergyMeasure"); + } + + + /// + /// Creates corresponding ifc unit for a measure name + /// + public static void CreateCorrespondingUnit(string measureName) + { + ForgeTypeId specType = UnitMappingUtil.GetUnitSpecTypeFromString(measureName); + UnitMappingUtil.GetOrCreateUnitInfo(specType); + } + + /// + /// Creates an IFCData object as an IfcMeasure of the right type + /// and creates the corresponding Revit unit. + /// + /// The int value. + /// The type of IfcMeasure (e.g. IfcForceMeasure). + /// The IFCData object. + public static IFCData CreateAsMeasureWithUnit(int value, string measureName) + { + CreateCorrespondingUnit(measureName); + return CreateAsMeasure(value, measureName); + } + + /// + /// Creates an IFCData object as an IfcMeasure of the right type + /// and creates the corresponding Revit unit. + /// + /// The double value. + /// The type of IfcMeasure (e.g. IfcForceMeasure). + /// The IFCData object. + public static IFCData CreateAsMeasureWithUnit(double value, string measureName) + { + CreateCorrespondingUnit(measureName); + return CreateAsMeasure(value, measureName); } /// @@ -282,7 +324,7 @@ public static IFCData CreateAsEnergyMeasure(double value) /// The IFCData object. public static IFCData CreateAsLinearMomentMeasure(double value) { - return CreateAsMeasure(value, "IfcLinearMomentMeasure"); + return CreateAsMeasureWithUnit(value, "IfcLinearMomentMeasure"); } /// @@ -292,7 +334,7 @@ public static IFCData CreateAsLinearMomentMeasure(double value) /// The IFCData object. public static IFCData CreateAsMassPerLengthMeasure(double value) { - return CreateAsMeasure(value, "IfcMassPerLengthMeasure"); + return CreateAsMeasureWithUnit(value, "IfcMassPerLengthMeasure"); } /// @@ -302,7 +344,7 @@ public static IFCData CreateAsMassPerLengthMeasure(double value) /// The IFCData object. public static IFCData CreateAsTorqueMeasure(double value) { - return CreateAsMeasure(value, "IfcTorqueMeasure"); + return CreateAsMeasureWithUnit(value, "IfcTorqueMeasure"); } /// @@ -312,7 +354,7 @@ public static IFCData CreateAsTorqueMeasure(double value) /// The IFCData object. public static IFCData CreateAsLinearStiffnessMeasure(double value) { - return CreateAsMeasure(value, "IfcLinearStiffnessMeasure"); + return CreateAsMeasureWithUnit(value, "IfcLinearStiffnessMeasure"); } /// @@ -322,7 +364,7 @@ public static IFCData CreateAsLinearStiffnessMeasure(double value) /// The IFCData object. public static IFCData CreateAsAngularVelocityMeasure(double value) { - return CreateAsMeasure(value, "IfcAngularVelocityMeasure"); + return CreateAsMeasureWithUnit(value, "IfcAngularVelocityMeasure"); } /// @@ -332,7 +374,7 @@ public static IFCData CreateAsAngularVelocityMeasure(double value) /// The IFCData object. public static IFCData CreateAsThermalResistanceMeasure(double value) { - return CreateAsMeasure(value, "IfcThermalResistanceMeasure"); + return CreateAsMeasureWithUnit(value, "IfcThermalResistanceMeasure"); } /// @@ -342,7 +384,7 @@ public static IFCData CreateAsThermalResistanceMeasure(double value) /// The IFCData object. public static IFCData CreateAsWarpingConstantMeasure(double value) { - return CreateAsMeasure(value, "IfcWarpingConstantMeasure"); + return CreateAsMeasureWithUnit(value, "IfcWarpingConstantMeasure"); } /// @@ -352,7 +394,7 @@ public static IFCData CreateAsWarpingConstantMeasure(double value) /// The IFCData object. public static IFCData CreateAsLinearVelocityMeasure(double value) { - return CreateAsMeasure(value, "IfcLinearVelocityMeasure"); + return CreateAsMeasureWithUnit(value, "IfcLinearVelocityMeasure"); } /// @@ -362,7 +404,7 @@ public static IFCData CreateAsLinearVelocityMeasure(double value) /// The IFCData object. public static IFCData CreateAsCountMeasure(double value) { - return CreateAsMeasure(value, "IfcCountMeasure"); + return CreateAsMeasureWithUnit(value, "IfcCountMeasure"); } /// @@ -372,7 +414,7 @@ public static IFCData CreateAsCountMeasure(double value) /// The IFCData object. public static IFCData CreateAsCountMeasure(int value) { - return CreateAsMeasure(value, "IfcCountMeasure"); + return CreateAsMeasureWithUnit(value, "IfcCountMeasure"); } /// @@ -382,7 +424,7 @@ public static IFCData CreateAsCountMeasure(int value) /// The IFCData object. public static IFCData CreateAsParameterValue(double value) { - return CreateAsMeasure(value, "IfcParameterValue"); + return CreateAsMeasureWithUnit(value, "IfcParameterValue"); } /// @@ -392,7 +434,7 @@ public static IFCData CreateAsParameterValue(double value) /// The IFCData object. public static IFCData CreateAsPowerMeasure(double value) { - return CreateAsMeasure(value, "IfcPowerMeasure"); + return CreateAsMeasureWithUnit(value, "IfcPowerMeasure"); } /// @@ -402,7 +444,7 @@ public static IFCData CreateAsPowerMeasure(double value) /// The IFCData object. public static IFCData CreateAsSoundPowerMeasure(double value) { - return CreateAsMeasure(value, "IfcSoundPowerMeasure"); + return CreateAsMeasureWithUnit(value, "IfcSoundPowerMeasure"); } /// @@ -412,7 +454,7 @@ public static IFCData CreateAsSoundPowerMeasure(double value) /// The IFCData object. public static IFCData CreateAsSoundPressureMeasure(double value) { - return CreateAsMeasure(value, "IfcSoundPressureMeasure"); + return CreateAsMeasureWithUnit(value, "IfcSoundPressureMeasure"); } /// @@ -422,27 +464,27 @@ public static IFCData CreateAsSoundPressureMeasure(double value) /// The IFCData object. public static IFCData CreateAsFrequencyMeasure(double value) { - return CreateAsMeasure(value, "IfcFrequencyMeasure"); + return CreateAsMeasureWithUnit(value, "IfcFrequencyMeasure"); } /// - /// Creates an IFCData object as IfcElectricalCurrentMeasure. + /// Creates an IFCData object as IfcElectricCurrentMeasure. /// /// The double value. /// The IFCData object. public static IFCData CreateAsElectricCurrentMeasure(double value) { - return CreateAsMeasure(value, "IfcElectricCurrentMeasure"); + return CreateAsMeasureWithUnit(value, "IfcElectricCurrentMeasure"); } /// - /// Creates an IFCData object as IfcElectricalVoltageMeasure. + /// Creates an IFCData object as IfcElectricVoltageMeasure. /// /// The double value. /// The IFCData object. public static IFCData CreateAsElectricVoltageMeasure(double value) { - return CreateAsMeasure(value, "IfcElectricVoltageMeasure"); + return CreateAsMeasureWithUnit(value, "IfcElectricVoltageMeasure"); } /// @@ -452,7 +494,7 @@ public static IFCData CreateAsElectricVoltageMeasure(double value) /// The IFCData object. public static IFCData CreateAsThermodynamicTemperatureMeasure(double value) { - return CreateAsMeasure(value, "IfcThermodynamicTemperatureMeasure"); + return CreateAsMeasureWithUnit(value, "IfcThermodynamicTemperatureMeasure"); } /// @@ -462,7 +504,7 @@ public static IFCData CreateAsThermodynamicTemperatureMeasure(double value) /// The IFCData object. public static IFCData CreateAsDynamicViscosityMeasure(double value) { - return CreateAsMeasure(value, "IfcDynamicViscosityMeasure"); + return CreateAsMeasureWithUnit(value, "IfcDynamicViscosityMeasure"); } /// @@ -472,7 +514,7 @@ public static IFCData CreateAsDynamicViscosityMeasure(double value) /// The IFCData object. public static IFCData CreateAsIsothermalMoistureCapacityMeasure(double value) { - return CreateAsMeasure(value, "IfcIsothermalMoistureCapacityMeasure"); + return CreateAsMeasureWithUnit(value, "IfcIsothermalMoistureCapacityMeasure"); } /// @@ -482,7 +524,7 @@ public static IFCData CreateAsIsothermalMoistureCapacityMeasure(double value) /// The IFCData object. public static IFCData CreateAsMassDensityMeasure(double value) { - return CreateAsMeasure(value, "IfcMassDensityMeasure"); + return CreateAsMeasureWithUnit(value, "IfcMassDensityMeasure"); } /// @@ -492,7 +534,7 @@ public static IFCData CreateAsMassDensityMeasure(double value) /// The IFCData object. public static IFCData CreateAsModulusOfElasticityMeasure(double value) { - return CreateAsMeasure(value, "IfcModulusOfElasticityMeasure"); + return CreateAsMeasureWithUnit(value, "IfcModulusOfElasticityMeasure"); } /// @@ -502,7 +544,7 @@ public static IFCData CreateAsModulusOfElasticityMeasure(double value) /// The IFCData object. public static IFCData CreateAsVaporPermeabilityMeasure(double value) { - return CreateAsMeasure(value, "IfcVaporPermeabilityMeasure"); + return CreateAsMeasureWithUnit(value, "IfcVaporPermeabilityMeasure"); } /// @@ -512,7 +554,7 @@ public static IFCData CreateAsVaporPermeabilityMeasure(double value) /// The IFCData object. public static IFCData CreateAsThermalExpansionCoefficientMeasure(double value) { - return CreateAsMeasure(value, "IfcThermalExpansionCoefficientMeasure"); + return CreateAsMeasureWithUnit(value, "IfcThermalExpansionCoefficientMeasure"); } /// @@ -522,9 +564,19 @@ public static IFCData CreateAsThermalExpansionCoefficientMeasure(double value) /// The IFCData object. public static IFCData CreateAsPressureMeasure(double value) { - return CreateAsMeasure(value, "IfcPressureMeasure"); + return CreateAsMeasureWithUnit(value, "IfcPressureMeasure"); } + /// + /// Creates an IFCData object as IfcMonetaryMeasure. + /// + /// The double value. + /// The IFCData object. + public static IFCData CreateAsMonetaryMeasure(double value) + { + return CreateAsMeasureWithUnit(value, "IfcMonetaryMeasure"); + } + /// /// Creates an IFCData object as IfcSpecificHeatCapacityMeasure. /// @@ -532,7 +584,7 @@ public static IFCData CreateAsPressureMeasure(double value) /// The IFCData object. public static IFCData CreateAsSpecificHeatCapacityMeasure(double value) { - return CreateAsMeasure(value, "IfcSpecificHeatCapacityMeasure"); + return CreateAsMeasureWithUnit(value, "IfcSpecificHeatCapacityMeasure"); } /// @@ -542,7 +594,7 @@ public static IFCData CreateAsSpecificHeatCapacityMeasure(double value) /// The IFCData object. public static IFCData CreateAsHeatingValueMeasure(double value) { - return CreateAsMeasure(value, "IfcHeatingValueMeasure"); + return CreateAsMeasureWithUnit(value, "IfcHeatingValueMeasure"); } /// @@ -552,7 +604,7 @@ public static IFCData CreateAsHeatingValueMeasure(double value) /// The IFCData object. public static IFCData CreateAsMoistureDiffusivityMeasure(double value) { - return CreateAsMeasure(value, "IfcMoistureDiffusivityMeasure"); + return CreateAsMeasureWithUnit(value, "IfcMoistureDiffusivityMeasure"); } /// @@ -562,7 +614,7 @@ public static IFCData CreateAsMoistureDiffusivityMeasure(double value) /// The IFCData object. public static IFCData CreateAsIonConcentrationMeasure(double value) { - return CreateAsMeasure(value, "IfcIonConcentrationMeasure"); + return CreateAsMeasureWithUnit(value, "IfcIonConcentrationMeasure"); } /// @@ -572,7 +624,7 @@ public static IFCData CreateAsIonConcentrationMeasure(double value) /// The IFCData object. public static IFCData CreateAsMomentOfInertiaMeasure(double value) { - return CreateAsMeasure(value, "IfcMomentOfInertiaMeasure"); + return CreateAsMeasureWithUnit(value, "IfcMomentOfInertiaMeasure"); } /// @@ -582,7 +634,7 @@ public static IFCData CreateAsMomentOfInertiaMeasure(double value) /// The IFCData object. public static IFCData CreateAsHeatFluxDensityMeasure(double value) { - return CreateAsMeasure(value, "IfcHeatFluxDensityMeasure"); + return CreateAsMeasureWithUnit(value, "IfcHeatFluxDensityMeasure"); } /// @@ -592,7 +644,7 @@ public static IFCData CreateAsHeatFluxDensityMeasure(double value) /// The IFCData object. public static IFCData CreateAsAreaDensityMeasure(double value) { - return CreateAsMeasure(value, "IfcAreaDensityMeasure"); + return CreateAsMeasureWithUnit(value, "IfcAreaDensityMeasure"); } /// @@ -602,8 +654,29 @@ public static IFCData CreateAsAreaDensityMeasure(double value) /// The IFCData object. public static IFCData CreateAsThermalConductivityMeasure(double value) { - return CreateAsMeasure(value, "IfcThermalConductivityMeasure"); + return CreateAsMeasureWithUnit(value, "IfcThermalConductivityMeasure"); + } + + /// + /// Creates an IFCData object as IfcRotationalFrequencyMeasure. + /// + /// The double value. + /// The IFCData object. + public static IFCData CreateAsRotationalFrequencyMeasure(double value) + { + return CreateAsMeasureWithUnit(value, "IfcRotationalFrequencyMeasure"); + } + + /// + /// Creates an IFCData object as IfcMassFlowRateMeasure. + /// + /// The double value. + /// The IFCData object. + public static IFCData CreateAsMassFlowRateMeasure(double value) + { + return CreateAsMeasureWithUnit(value, "IfcMassFlowRateMeasure"); } + /// /// Creates an IFCData object as IfcThermalTransmittanceMeasure. @@ -612,7 +685,7 @@ public static IFCData CreateAsThermalConductivityMeasure(double value) /// The IFCData object. public static IFCData CreateAsThermalTransmittanceMeasure(double value) { - return CreateAsMeasure(value, "IfcThermalTransmittanceMeasure"); + return CreateAsMeasureWithUnit(value, "IfcThermalTransmittanceMeasure"); } /// @@ -683,7 +756,7 @@ public static IFCData CreateRatioMeasureDataCommon(double value, PropertyType pr /// The IFCData object. public static IFCData CreateAsVolumetricFlowRateMeasure(double value) { - return CreateAsMeasure(value, "IfcVolumetricFlowRateMeasure"); + return CreateAsMeasureWithUnit(value, "IfcVolumetricFlowRateMeasure"); } /// @@ -693,7 +766,7 @@ public static IFCData CreateAsVolumetricFlowRateMeasure(double value) /// The IFCData object. public static IFCData CreateAsIlluminanceMeasure(double value) { - return CreateAsMeasure(value, "IfcIlluminanceMeasure"); + return CreateAsMeasureWithUnit(value, "IfcIlluminanceMeasure"); } /// @@ -703,7 +776,7 @@ public static IFCData CreateAsIlluminanceMeasure(double value) /// The IFCData object. public static IFCData CreateAsLuminousFluxMeasure(double value) { - return CreateAsMeasure(value, "IfcLuminousFluxMeasure"); + return CreateAsMeasureWithUnit(value, "IfcLuminousFluxMeasure"); } /// @@ -713,7 +786,7 @@ public static IFCData CreateAsLuminousFluxMeasure(double value) /// The IFCData object. public static IFCData CreateAsLuminousIntensityMeasure(double value) { - return CreateAsMeasure(value, "IfcLuminousIntensityMeasure"); + return CreateAsMeasureWithUnit(value, "IfcLuminousIntensityMeasure"); } /// @@ -723,7 +796,7 @@ public static IFCData CreateAsLuminousIntensityMeasure(double value) /// The IFCData object. public static IFCData CreateAsForceMeasure(double value) { - return CreateAsMeasure(value, "IfcForceMeasure"); + return CreateAsMeasureWithUnit(value, "IfcForceMeasure"); } /// @@ -733,7 +806,7 @@ public static IFCData CreateAsForceMeasure(double value) /// the IFCData object public static IFCData CreateAsLinearForceMeasure(double value) { - return CreateAsMeasure(value, "IfcLinearForceMeasure"); + return CreateAsMeasureWithUnit(value, "IfcLinearForceMeasure"); } /// @@ -743,7 +816,7 @@ public static IFCData CreateAsLinearForceMeasure(double value) /// the IFCData object public static IFCData CreateAsMassMeasure(double value) { - return CreateAsMeasure(value, "IfcMassMeasure"); + return CreateAsMeasureWithUnit(value, "IfcMassMeasure"); } /// @@ -753,7 +826,7 @@ public static IFCData CreateAsMassMeasure(double value) /// the IFCData object public static IFCData CreateAsTimeMeasure(double value) { - return CreateAsMeasure(value, "IfcTimeMeasure"); + return CreateAsMeasureWithUnit(value, "IfcTimeMeasure"); } /// @@ -763,7 +836,7 @@ public static IFCData CreateAsTimeMeasure(double value) /// the IFCData object public static IFCData CreateAsPlanarForceMeasure(double value) { - return CreateAsMeasure(value, "IfcPlanarForceMeasure"); + return CreateAsMeasureWithUnit(value, "IfcPlanarForceMeasure"); } /// diff --git a/Source/Revit.IFC.Export/Toolkit/IFCInstanceExporter.cs b/Source/Revit.IFC.Export/Toolkit/IFCInstanceExporter.cs index 761549e7..e486890c 100644 --- a/Source/Revit.IFC.Export/Toolkit/IFCInstanceExporter.cs +++ b/Source/Revit.IFC.Export/Toolkit/IFCInstanceExporter.cs @@ -25,6 +25,8 @@ using Revit.IFC.Export.Utility; using Revit.IFC.Common.Enums; using Revit.IFC.Common.Utility; +using Revit.IFC.Export.Exporter.PropertySet; +using System.Xml.Linq; namespace Revit.IFC.Export.Toolkit { @@ -435,19 +437,25 @@ private static void SetPropertyDefinition(IFCAnyHandle propertyDefinition, Eleme string guid, IFCAnyHandle ownerHistory, string name, string description, string objectType) { - string overrideObjectType = objectType; - if (element != null) + string overrideObjectType = (element != null) ? + NamingUtil.GetObjectTypeOverride(obj, element, objectType) : + objectType; + + if (string.IsNullOrEmpty(overrideObjectType) && (element != null)) { - if (string.IsNullOrEmpty(objectType)) - objectType = NamingUtil.GetFamilyAndTypeName(element); - overrideObjectType = NamingUtil.GetObjectTypeOverride(obj, element, objectType); + overrideObjectType = NamingUtil.GetFamilyAndTypeName(element); } + IFCAnyHandleUtil.SetAttribute(obj, "ObjectType", overrideObjectType); if (ExporterCacheManager.ExportOptionsCache.ExportAs2x2) + { SetRoot(obj, element, guid, ownerHistory, name, description); + } else + { SetObjectDefinition(obj, element, guid, ownerHistory, name, description); + } } /// @@ -554,6 +562,50 @@ private static void SetPropertyDefinition(IFCAnyHandle propertyDefinition, Eleme } } + /// + /// Sets attributes to IfcFacilityPart. + /// + /// The IfcFacilityPart. + /// The GUID. + /// The owner history. + /// The name. + /// The description. + /// The object type. + /// The object placement. + /// The representation object. + /// The long name. + /// The composition type. + private static void SetFacilityPart(IFCAnyHandle facilityPart, Element element, + string guid, IFCAnyHandle ownerHistory, string name, string description, string objectType, + IFCAnyHandle objectPlacement, IFCAnyHandle representation, string longName, + IFCElementComposition compositionType) + { + SetSpatialStructureElement(facilityPart, element, guid, ownerHistory, name, description, objectType, + objectPlacement, representation, longName, compositionType); + } + + /// + /// Sets attributes to IfcFacility. + /// + /// The IfcFacility. + /// The GUID. + /// The owner history. + /// The name. + /// The description. + /// The object type. + /// The object placement. + /// The representation object. + /// The long name. + /// The composition type. + private static void SetFacility(IFCAnyHandle facility, Element element, + string guid, IFCAnyHandle ownerHistory, string name, string description, string objectType, + IFCAnyHandle objectPlacement, IFCAnyHandle representation, string longName, + IFCElementComposition compositionType) + { + SetSpatialStructureElement(facility, element, guid, ownerHistory, name, description, objectType, + objectPlacement, representation, longName, compositionType); + } + /// /// Sets attributes to IfcSpatialStructureElement. /// @@ -568,11 +620,9 @@ private static void SetPropertyDefinition(IFCAnyHandle propertyDefinition, Eleme /// The long name. /// The composition type. private static void SetSpatialStructureElement(IFCAnyHandle spatialStructureElement, Element element, - string guid, IFCAnyHandle ownerHistory, string name, string description, - string objectType, - IFCAnyHandle objectPlacement, IFCAnyHandle representation, - string longName, - IFCElementComposition compositionType) + string guid, IFCAnyHandle ownerHistory, string name, string description, + string objectType, IFCAnyHandle objectPlacement, IFCAnyHandle representation, string longName, + IFCElementComposition compositionType) { IFCAnyHandleUtil.SetAttribute(spatialStructureElement, "CompositionType", compositionType); if (ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4) @@ -1806,12 +1856,12 @@ public static IFCAnyHandle CreateLocalPlacement(IFCFile file, IFCAnyHandle place IFCAnyHandleUtil.SetAttribute(building, "ElevationOfRefHeight", elevationOfRefHeight); IFCAnyHandleUtil.SetAttribute(building, "ElevationOfTerrain", elevationOfTerrain); IFCAnyHandleUtil.SetAttribute(building, "BuildingAddress", buildingAddress); - SetSpatialStructureElement(building, null, guid, ownerHistory, name, description, objectType, objectPlacement, representation, longName, compositionType); + SetFacility(building, null, guid, ownerHistory, name, description, objectType, objectPlacement, representation, longName, compositionType); return building; } /// - /// Creates a handle representing an IfcBuildingStorey and assigns it to the file. + /// Creates an IfcBridge, and assigns it to the file. /// /// The file. /// The GUID. @@ -1823,13 +1873,111 @@ public static IFCAnyHandle CreateLocalPlacement(IFCFile file, IFCAnyHandle place /// The representation object. /// The long name. /// The composition type. - /// The elevation with flooring measurement. + /// The predefined type of the bridge. /// The handle. - public static IFCAnyHandle CreateBuildingStorey(ExporterIFC exporterIFC, Level level, IFCAnyHandle ownerHistory, string objectType, IFCAnyHandle objectPlacement, - IFCElementComposition compositionType, double elevation) + public static IFCAnyHandle CreateBridge(ExporterIFC exporterIFC, string guid, IFCAnyHandle ownerHistory, + string name, string description, string objectType, IFCAnyHandle objectPlacement, IFCAnyHandle representation, + string longName, IFCElementComposition compositionType, string predefinedType) + { + IFCAnyHandle bridge = CreateInstance(exporterIFC.GetFile(), IFCEntityType.IfcBridge, null); + IFCAnyHandleUtil.SetAttribute(bridge, "PredefinedType", predefinedType); + SetFacility(bridge, null, guid, ownerHistory, name, description, objectType, objectPlacement, representation, longName, compositionType); + return bridge; + } + + /// + /// Creates an IfcRoad, and assigns it to the file. + /// + /// The file. + /// The GUID. + /// The owner history. + /// The name. + /// The description. + /// The object type. + /// The object placement. + /// The representation object. + /// The long name. + /// The composition type. + /// The predefined type of the bridge. + /// The handle. + public static IFCAnyHandle CreateRoad(ExporterIFC exporterIFC, string guid, IFCAnyHandle ownerHistory, + string name, string description, string objectType, IFCAnyHandle objectPlacement, IFCAnyHandle representation, + string longName, IFCElementComposition compositionType, string predefinedType) { + IFCAnyHandle road = CreateInstance(exporterIFC.GetFile(), IFCEntityType.IfcRoad, null); + IFCAnyHandleUtil.SetAttribute(road, "PredefinedType", predefinedType); + SetFacility(road, null, guid, ownerHistory, name, description, objectType, objectPlacement, representation, longName, compositionType); + return road; + } + /// + /// Creates an IfcRailway, and assigns it to the file. + /// + /// The file. + /// The GUID. + /// The owner history. + /// The name. + /// The description. + /// The object type. + /// The object placement. + /// The representation object. + /// The long name. + /// The composition type. + /// The predefined type of the bridge. + /// The handle. + public static IFCAnyHandle CreateRailway(ExporterIFC exporterIFC, string guid, IFCAnyHandle ownerHistory, + string name, string description, string objectType, IFCAnyHandle objectPlacement, IFCAnyHandle representation, + string longName, IFCElementComposition compositionType, string predefinedType) + { + IFCAnyHandle railway = CreateInstance(exporterIFC.GetFile(), IFCEntityType.IfcRailway, null); + IFCAnyHandleUtil.SetAttribute(railway, "PredefinedType", predefinedType); + SetFacility(railway, null, guid, ownerHistory, name, description, objectType, objectPlacement, representation, longName, compositionType); + return railway; + } + /// + /// Creates an IfcRailway, and assigns it to the file. + /// + /// The file. + /// The GUID. + /// The owner history. + /// The name. + /// The description. + /// The object type. + /// The object placement. + /// The representation object. + /// The long name. + /// The composition type. + /// The predefined type of the bridge. + /// The handle. + public static IFCAnyHandle CreateMarineFacility(ExporterIFC exporterIFC, string guid, IFCAnyHandle ownerHistory, + string name, string description, string objectType, IFCAnyHandle objectPlacement, IFCAnyHandle representation, + string longName, IFCElementComposition compositionType, string predefinedType) + { + IFCAnyHandle marineFacility = CreateInstance(exporterIFC.GetFile(), IFCEntityType.IfcMarineFacility, null); + IFCAnyHandleUtil.SetAttribute(marineFacility, "PredefinedType", predefinedType); + SetFacility(marineFacility, null, guid, ownerHistory, name, description, objectType, objectPlacement, representation, longName, compositionType); + return marineFacility; + } + + /// + /// Creates a handle representing an IfcBuildingStorey and assigns it to the file. + /// + /// The file. + /// The GUID. + /// The owner history. + /// The name. + /// The description. + /// The object type. + /// The object placement. + /// The representation object. + /// The long name. + /// The composition type. + /// The elevation with flooring measurement. + /// The handle. + public static IFCAnyHandle CreateBuildingStorey(ExporterIFC exporterIFC, Level level, IFCAnyHandle ownerHistory, string objectType, IFCAnyHandle objectPlacement, + IFCElementComposition compositionType, double elevation) + { IFCAnyHandle buildingStorey = CreateInstance(exporterIFC.GetFile(), IFCEntityType.IfcBuildingStorey, null); string guid = GUIDUtil.GetLevelGUID(level); string name = NamingUtil.GetNameOverride(buildingStorey, level, level.Name); @@ -1837,10 +1985,120 @@ public static IFCAnyHandle CreateLocalPlacement(IFCFile file, IFCAnyHandle place string longName = NamingUtil.GetLongNameOverride(level, level.Name); IFCAnyHandleUtil.SetAttribute(buildingStorey, "Elevation", elevation); - SetSpatialStructureElement(buildingStorey, level, guid, ownerHistory, name, description, objectType, objectPlacement, null, longName, compositionType); + SetFacilityPart(buildingStorey, level, guid, ownerHistory, name, description, objectType, objectPlacement, null, longName, compositionType); return buildingStorey; } + /// + /// Creates a handle representing an IfcMarinePart and assigns it to the file. + /// + /// The file. + /// The GUID. + /// The owner history. + /// The name. + /// The description. + /// The object type. + /// The object placement. + /// The representation object. + /// The long name. + /// The composition type. + /// The handle. + public static IFCAnyHandle CreateMarinePart(ExporterIFC exporterIFC, Level level, IFCAnyHandle ownerHistory, string objectType, IFCAnyHandle objectPlacement, + IFCElementComposition compositionType) + { + IFCAnyHandle marinePart = CreateInstance(exporterIFC.GetFile(), IFCEntityType.IfcMarinePart, null); + string guid = GUIDUtil.GetLevelGUID(level); + string name = NamingUtil.GetNameOverride(marinePart, level, level.Name); + string description = NamingUtil.GetDescriptionOverride(level, null); + string longName = NamingUtil.GetLongNameOverride(level, level.Name); + + SetFacilityPart(marinePart, level, guid, ownerHistory, name, description, objectType, objectPlacement, null, longName, compositionType); + return marinePart; + } + + /// + /// Creates a handle representing an IfcRoadPart and assigns it to the file. + /// + /// The file. + /// The GUID. + /// The owner history. + /// The name. + /// The description. + /// The object type. + /// The object placement. + /// The representation object. + /// The long name. + /// The composition type. + /// The handle. + public static IFCAnyHandle CreateRoadPart(ExporterIFC exporterIFC, Level level, IFCAnyHandle ownerHistory, string objectType, IFCAnyHandle objectPlacement, + IFCElementComposition compositionType) + { + IFCAnyHandle roadPart = CreateInstance(exporterIFC.GetFile(), IFCEntityType.IfcRoadPart, null); + string guid = GUIDUtil.GetLevelGUID(level); + string name = NamingUtil.GetNameOverride(roadPart, level, level.Name); + string description = NamingUtil.GetDescriptionOverride(level, null); + string longName = NamingUtil.GetLongNameOverride(level, level.Name); + + SetFacilityPart(roadPart, level, guid, ownerHistory, name, description, objectType, objectPlacement, null, longName, compositionType); + return roadPart; + } + + /// + /// Creates a handle representing an IfcRailwayPart and assigns it to the file. + /// + /// The file. + /// The GUID. + /// The owner history. + /// The name. + /// The description. + /// The object type. + /// The object placement. + /// The representation object. + /// The long name. + /// The composition type. + /// The handle. + public static IFCAnyHandle CreateRailwayPart(ExporterIFC exporterIFC, Level level, IFCAnyHandle ownerHistory, string objectType, IFCAnyHandle objectPlacement, + IFCElementComposition compositionType) + { + IFCAnyHandle railwayPart = CreateInstance(exporterIFC.GetFile(), IFCEntityType.IfcRailwayPart, null); + string guid = GUIDUtil.GetLevelGUID(level); + string name = NamingUtil.GetNameOverride(railwayPart, level, level.Name); + string description = NamingUtil.GetDescriptionOverride(level, null); + string longName = NamingUtil.GetLongNameOverride(level, level.Name); + + SetFacilityPart(railwayPart, level, guid, ownerHistory, name, description, objectType, objectPlacement, null, longName, compositionType); + return railwayPart; + } + + /// + /// Creates a handle representing an IfcBridgePart and assigns it to the file. + /// + /// The file. + /// The GUID. + /// The owner history. + /// The name. + /// The description. + /// The object type. + /// The object placement. + /// The representation object. + /// The long name. + /// The composition type. + /// The predefined type of the bridge part. + /// The handle. + public static IFCAnyHandle CreateBridgePart(ExporterIFC exporterIFC, Level level, IFCAnyHandle ownerHistory, string objectType, IFCAnyHandle objectPlacement, + IFCElementComposition compositionType, string predefinedType) + { + IFCAnyHandle bridgePart = CreateInstance(exporterIFC.GetFile(), IFCEntityType.IfcBridgePart, null); + string guid = GUIDUtil.GetLevelGUID(level); + string name = NamingUtil.GetNameOverride(bridgePart, level, level.Name); + string description = NamingUtil.GetDescriptionOverride(level, null); + string longName = NamingUtil.GetLongNameOverride(level, level.Name); + + IFCAnyHandleUtil.SetAttribute(bridgePart, "PredefinedType", predefinedType); + SetFacilityPart(bridgePart, level, guid, ownerHistory, name, description, objectType, objectPlacement, null, longName, compositionType); + return bridgePart; + } + /// /// Creates a handle representing an IfcSpace and assigns it to the file. /// @@ -2768,6 +3026,16 @@ public static IFCAnyHandle CreateUnitAssignment(IFCFile file, HashSet + /// Validate that the parameters for IfcCircle are valid. + /// + /// The radius of the circle. + /// True if the circle is valid. + public static bool ValidateCircle(double radius) + { + return radius >= MathUtil.Eps(); + } + /// /// Creates a handle representing an IfcCircle and assigns it to the file. /// @@ -2777,7 +3045,7 @@ public static IFCAnyHandle CreateUnitAssignment(IFCFile file, HashSetThe handle. public static IFCAnyHandle CreateCircle(IFCFile file, IFCAnyHandle position, double radius) { - if (radius < MathUtil.Eps()) + if (!ValidateCircle(radius)) throw new ArgumentException("Radius is tiny, zero, or negative."); IFCAnyHandle circle = CreateInstance(file, IFCEntityType.IfcCircle, null); @@ -2786,6 +3054,17 @@ public static IFCAnyHandle CreateCircle(IFCFile file, IFCAnyHandle position, dou return circle; } + /// + /// Validate that the parameters for IfcEllipse are valid. + /// + /// The radius in the direction of X in the local coordinate system. + /// The radius in the direction of Y in the local coordinate system. + /// True if the ellipse is valid. + public static bool ValidateEllipse(double semiAxis1, double semiAxis2) + { + return semiAxis1 >= MathUtil.Eps() && semiAxis2 >= MathUtil.Eps(); + } + /// /// Creates a handle representing an IfcEllipse and assigns it to the file. /// @@ -2796,9 +3075,7 @@ public static IFCAnyHandle CreateCircle(IFCFile file, IFCAnyHandle position, dou /// The handle. public static IFCAnyHandle CreateEllipse(IFCFile file, IFCAnyHandle position, double semiAxis1, double semiAxis2) { - if (semiAxis1 < MathUtil.Eps()) - throw new ArgumentException("semiAxis1 is tiny, zero, or negative."); - if (semiAxis2 < MathUtil.Eps()) + if (!ValidateEllipse(semiAxis1, semiAxis2)) throw new ArgumentException("semiAxis2 is tiny, zero, or negative."); IFCAnyHandle ellipse = CreateInstance(file, IFCEntityType.IfcEllipse, null); @@ -3651,9 +3928,6 @@ public static void SetGenericTypeNonOptionalAttributes(IFCAnyHandle handleType, public static void SetPredefinedType(IFCAnyHandle genericIFCEntity, IFCExportInfoPair entityToCreate) { - if (string.IsNullOrEmpty(entityToCreate.ValidatedPredefinedType)) - return; - IFCVersion version = ExporterCacheManager.ExportOptionsCache.FileVersion; IFCEntityType entityType = entityToCreate.ExportInstance; @@ -3666,7 +3940,7 @@ public static void SetGenericTypeNonOptionalAttributes(IFCAnyHandle handleType, if (predefinedTypeAttributeName == null && !MissingAttributeCache.Find(version, entityType)) predefinedTypeAttributeName = "PredefinedType"; if (predefinedTypeAttributeName != null) - IFCAnyHandleUtil.SetAttribute(genericIFCEntity, predefinedTypeAttributeName, entityToCreate.ValidatedPredefinedType, true); + IFCAnyHandleUtil.SetAttribute(genericIFCEntity, predefinedTypeAttributeName, entityToCreate.GetPredefinedTypeOrDefault(), true); } catch { @@ -3755,15 +4029,12 @@ public static void SetGenericTypeNonOptionalAttributes(IFCAnyHandle handleType, IFCAnyHandle genericIFCType = CreateInstance(file, entityTypeToUse, elementType); SetElementType(genericIFCType, elementType, guid, propertySets, representationMaps); - if (!string.IsNullOrEmpty(typeEntityToCreate.ValidatedPredefinedType)) + // Earlier types in IFC2x_ may not have PredefinedType property. Ignore error + try { - // Earlier types in IFC2x_ may not have PredefinedType property. Ignore error - try - { - IFCAnyHandleUtil.SetAttribute(genericIFCType, "PredefinedType", typeEntityToCreate.ValidatedPredefinedType, true); - } - catch { } + IFCAnyHandleUtil.SetAttribute(genericIFCType, "PredefinedType", typeEntityToCreate.GetPredefinedTypeOrDefault(), true); } + catch { } SetGenericTypeNonOptionalAttributes(genericIFCType, typeEntityToCreate.ExportType); @@ -3834,8 +4105,6 @@ public static void SetGenericTypeNonOptionalAttributes(IFCAnyHandle handleType, if (!ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4) { - if (string.IsNullOrEmpty(predefinedType)) - predefinedType = "NOTDEFINED"; predefinedType = IFCValidateEntry.GetValidIFCPredefinedTypeType(predefinedType, predefinedType, "IFCFurnitureType"); IFCAnyHandleUtil.SetAttribute(furnitureType, "PredefinedType", predefinedType, true); } @@ -3966,8 +4235,7 @@ public static void SetGenericTypeNonOptionalAttributes(IFCAnyHandle handleType, IFCAnyHandle buildingSystem = CreateInstance(file, IFCEntityType.IfcBuildingSystem, null); SetGroup(buildingSystem, guid, ownerHistory, name, description, objectType); - if (!string.IsNullOrEmpty(entityToCreate.ValidatedPredefinedType)) - IFCAnyHandleUtil.SetAttribute(buildingSystem, "PredefinedType", entityToCreate.ValidatedPredefinedType, true); + IFCAnyHandleUtil.SetAttribute(buildingSystem, "PredefinedType", entityToCreate.GetPredefinedTypeOrDefault(), true); if (!string.IsNullOrEmpty(longName)) IFCAnyHandleUtil.SetAttribute(buildingSystem, "LongName", longName, false); @@ -6641,7 +6909,10 @@ public static IFCAnyHandle CreateIndexedColourMap(IFCFile file, IFCAnyHandle map IFCAnyHandle indexedColourMap = CreateInstance(file, IFCEntityType.IfcIndexedColourMap, null); IFCAnyHandleUtil.SetAttribute(indexedColourMap, "MappedTo", mappedTo); if (opacity.HasValue) - IFCAnyHandleUtil.SetAttribute(indexedColourMap, "Opacity", opacity); + { + double inRangeOpacity = Math.Min(Math.Max(opacity.Value, 0.0), 1.0); + IFCAnyHandleUtil.SetAttribute(indexedColourMap, "Opacity", inRangeOpacity); + } IFCAnyHandleUtil.SetAttribute(indexedColourMap, "Colours", colours); IFCAnyHandleUtil.SetAttribute(indexedColourMap, "ColourIndex", colourIndex); return indexedColourMap; diff --git a/Source/Revit.IFC.Export/Toolkit/PlacementSetter.cs b/Source/Revit.IFC.Export/Toolkit/PlacementSetter.cs index 80029180..a3d954ef 100644 --- a/Source/Revit.IFC.Export/Toolkit/PlacementSetter.cs +++ b/Source/Revit.IFC.Export/Toolkit/PlacementSetter.cs @@ -339,7 +339,7 @@ public IFCLevelInfo GetOffsetLevelInfoAndHandle(double offset, double scale, Doc { // the cache contains levels from all the exported documents // if the export is performed for a linked document, filter the levels that are not from this document - if (ExporterCacheManager.ExportOptionsCache.ExportingSeparateLink()) + if (ExporterCacheManager.ExportOptionsCache.ExportLinkedFileAs != LinkedFileExportAs.DontExport) { Element levelElem = document.GetElement(levelInfoPair.Key); if (levelElem == null || !(levelElem is Level)) @@ -491,7 +491,7 @@ private void commonInit(ExporterIFC exporterIFC, Element elem, Transform familyT { // the cache contains levels from all the exported documents // if the export is performed for a linked document, filter the levels that are not from this document - if (ExporterCacheManager.ExportOptionsCache.ExportingSeparateLink()) + if (ExporterCacheManager.ExportOptionsCache.ExportLinkedFileAs != LinkedFileExportAs.DontExport) { Element levelElem = doc.GetElement(levelInfoPair.Key); if (levelElem == null || !(levelElem is Level)) @@ -528,7 +528,7 @@ private void commonInit(ExporterIFC exporterIFC, Element elem, Transform familyT { // the cache contains levels from all the exported documents // if the export is performed for a linked document, filter the levels that are not from this document - if (ExporterCacheManager.ExportOptionsCache.ExportingSeparateLink()) + if (ExporterCacheManager.ExportOptionsCache.ExportLinkedFileAs != LinkedFileExportAs.DontExport) { Element levelElem = doc.GetElement(levelInfoPair.Key); if (levelElem == null || !(levelElem is Level)) diff --git a/Source/Revit.IFC.Export/Utility/CategoryUtil.cs b/Source/Revit.IFC.Export/Utility/CategoryUtil.cs index d69e3108..ab4d9663 100644 --- a/Source/Revit.IFC.Export/Utility/CategoryUtil.cs +++ b/Source/Revit.IFC.Export/Utility/CategoryUtil.cs @@ -48,7 +48,7 @@ public static Category GetSafeCategory(Element element) if (element == null) return null; - // Special cases below - at the moment only one, for ModelCurves. + // Special cases below. if (element is ModelCurve) { CurveElement modelCurve = element as ModelCurve; @@ -56,6 +56,14 @@ public static Category GetSafeCategory(Element element) if (lineStyle != null) return lineStyle.GraphicsStyleCategory; } + else if (element is ModelText) + { + Parameter parameter = element.GetParameter(ParameterTypeId.ModelCategoryIdParam); + if (parameter != null && parameter.HasValue && parameter.StorageType == StorageType.ElementId) + { + return Category.GetCategory(element.Document, parameter.AsElementId()); + } + } return element.Category; } @@ -154,13 +162,6 @@ public static IFCAnyHandle CreateMaterialList(IFCFile file, IList return matList; } - public static IFCAnyHandle CreateMaterialLayerSetUsage(IFCFile file, IFCAnyHandle materialLayerSet, IFCLayerSetDirection direction, - IFCDirectionSense directionSense, double offset) - { - return IFCInstanceExporter.CreateMaterialLayerSetUsage(file, materialLayerSet, - direction, directionSense, offset); - } - public static IFCAnyHandle CreateMaterialProfileSetUsage(IFCFile file, IFCAnyHandle materialProfileSet, int? cardinalPoint) { @@ -257,11 +258,11 @@ private static bool CacheIsElementExternal(ElementId elementId, bool isExternal) /// All other elements are internal. /// /// The element. - /// True if the element is external, false otherwise. - public static bool IsElementExternal(Element element) + /// True if the element is external, false otherwise and null if will not export the value. + public static bool? IsElementExternal(Element element) { - if (element == null) - return false; + if (element == null || element is ElementType) + return null; // Look for a parameter "IsExternal", potentially localized. ElementId elementId = element.Id; @@ -289,10 +290,6 @@ public static bool IsElementExternal(Element element) elementType = element.Document.GetElement(element.GetTypeId()); } - else if (element is ElementType) - { - elementType = element; - } // Many element types have the FUNCTION_PARAM parameter. If this is set, use its value. int elementFunction; @@ -441,9 +438,8 @@ public static void CreateMaterialAssociation(ExporterIFC exporterIFC, IFCAnyHand // in IFC4 we will create IfcConstituentSet instead of MaterialList, create the associated IfcConstituent here from IfcMaterial foreach (ElementId materialId in alreadySeenIds) { - IFCAnyHandle constituentHnd = GetOrCreateMaterialConstituent(exporterIFC, materialId); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(constituentHnd)) - constituentSet.Add(constituentHnd); + constituentSet.AddIfNotNull(GetOrCreateMaterialConstituent(exporterIFC, + materialId)); } GetOrCreateMaterialConstituentSet(file, instanceHandle, constituentSet); @@ -566,9 +562,8 @@ public static void CreateMaterialAssociationWithShapeAspect(ExporterIFC exporter // in IFC4 we will create IfcConstituentSet instead of MaterialList, create the associated IfcConstituent here from IfcMaterial foreach (KeyValuePair> repItemInfoSet in repItemInfoGroup) { - IFCAnyHandle constituentHnd = GetOrCreateMaterialConstituent(exporterIFC, repItemInfoSet.Key); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(constituentHnd)) - constituentSet.Add(constituentHnd); + constituentSet.AddIfNotNull(GetOrCreateMaterialConstituent(exporterIFC, + repItemInfoSet.Key)); RepresentationUtil.CreateRepForShapeAspect(exporterIFC, element, prodRep, repType, repItemInfoSet.Key.ComponentCat, repItemInfoSet.Value); } @@ -759,10 +754,9 @@ public static IFCAnyHandle GetOrCreateMaterialHandle(ExporterIFC exporterIFC, El IFCAnyHandle styledRepItem = null; IFCAnyHandle matStyleHnd = GetOrCreateMaterialStyle(document, file, materialId); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(matStyleHnd) && !ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView) + if (!ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView && + styles.AddIfNotNull(matStyleHnd)) { - styles.Add(matStyleHnd); - bool supportCutStyles = !ExporterCacheManager.ExportOptionsCache.ExportAsCoordinationView2; if (fillPatternId != ElementId.InvalidElementId && supportCutStyles) { diff --git a/Source/Revit.IFC.Export/Utility/DoorWindowDelayedOpeningCreator.cs b/Source/Revit.IFC.Export/Utility/DoorWindowDelayedOpeningCreator.cs index da7d47dd..a46c5f45 100644 --- a/Source/Revit.IFC.Export/Utility/DoorWindowDelayedOpeningCreator.cs +++ b/Source/Revit.IFC.Export/Utility/DoorWindowDelayedOpeningCreator.cs @@ -17,16 +17,12 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // -using System; using System.Collections.Generic; -using System.Text; -using Autodesk.Revit; using Autodesk.Revit.DB; using Autodesk.Revit.DB.IFC; using Revit.IFC.Common.Enums; using Revit.IFC.Common.Utility; using Revit.IFC.Export.Toolkit; -using Revit.IFC.Export.Exporter; namespace Revit.IFC.Export.Utility { @@ -147,6 +143,49 @@ public void CopyGeometry(DoorWindowDelayedOpeningCreator otherCreator) HasValidGeometry = true; } + /// + /// Adds geometries from another creator. + /// + /// The other creator. + public void AddGeometry(DoorWindowDelayedOpeningCreator otherCreator) + { + // Nothing to add. + if (!otherCreator.HasValidGeometry) + { + return; + } + + bool copyExtrusionData = otherCreator.ExtrusionData != null; + if (ExtrusionData == null && copyExtrusionData) + { + ExtrusionData = otherCreator.ExtrusionData; + copyExtrusionData = false; + } + + bool copySolids = otherCreator.Solids != null; + if (Solids == null && copySolids) + { + Solids = otherCreator.Solids; + copySolids = false; + } + + if (copyExtrusionData) + { + foreach (IFCExtrusionData extrusionData in otherCreator.ExtrusionData) + { + ExtrusionData.Add(extrusionData); + } + } + + if (copySolids) + { + foreach (Solid solid in otherCreator.Solids) + { + Solids.Add(solid); + } + } + } + /// /// Excutes the creator. /// diff --git a/Source/Revit.IFC.Export/Utility/DoorWindowDelayedOpeningCreatorCache.cs b/Source/Revit.IFC.Export/Utility/DoorWindowDelayedOpeningCreatorCache.cs index 62a0b1dd..826d4fe3 100644 --- a/Source/Revit.IFC.Export/Utility/DoorWindowDelayedOpeningCreatorCache.cs +++ b/Source/Revit.IFC.Export/Utility/DoorWindowDelayedOpeningCreatorCache.cs @@ -42,7 +42,7 @@ public class DoorWindowDelayedOpeningCreatorCache /// Adds a new DoorWindowDelayedOpeningCreator. /// /// The creator. - public void Add(DoorWindowDelayedOpeningCreator creator) + public void Add(DoorWindowDelayedOpeningCreator creator, bool extend) { if (creator == null) return; @@ -62,17 +62,11 @@ public void Add(DoorWindowDelayedOpeningCreator creator) // from DoorWindowInfo has higher priority if (oldCreator.CreatedFromDoorWindowInfo) { - if (!oldCreator.HasValidGeometry && creator.HasValidGeometry) - { - oldCreator.CopyGeometry(creator); - } + CopyOrAddGeometry(oldCreator, creator, extend); } else if (creator.CreatedFromDoorWindowInfo) { - if (!creator.HasValidGeometry && oldCreator.HasValidGeometry) - { - creator.CopyGeometry(oldCreator); - } + CopyOrAddGeometry(creator, oldCreator, extend); existingOpenings[levelIdToUse] = creator; } } @@ -91,9 +85,23 @@ public void ExecuteCreators(ExporterIFC exporterIFC, Document doc) { foreach (DoorWindowDelayedOpeningCreator creator in creators.Values) { - creator.Execute(exporterIFC, doc); + //Geometry can become invalid when ExtrusionData or Solids are null or count is 0 + if (creator.HasValidGeometry) + creator.Execute(exporterIFC, doc); } } } + + private void CopyOrAddGeometry(DoorWindowDelayedOpeningCreator oldCreator, DoorWindowDelayedOpeningCreator newCreator, bool extend) + { + if (!oldCreator.HasValidGeometry && newCreator.HasValidGeometry) + { + oldCreator.CopyGeometry(newCreator); + } + else if (oldCreator.HasValidGeometry && newCreator.HasValidGeometry && extend) + { + oldCreator.AddGeometry(newCreator); + } + } } } \ No newline at end of file diff --git a/Source/Revit.IFC.Export/Utility/DoorWindowInfo.cs b/Source/Revit.IFC.Export/Utility/DoorWindowInfo.cs index 82f89ff7..732fffb6 100644 --- a/Source/Revit.IFC.Export/Utility/DoorWindowInfo.cs +++ b/Source/Revit.IFC.Export/Utility/DoorWindowInfo.cs @@ -431,19 +431,13 @@ private void Initialize(bool isDoor, bool isWindow, FamilyInstance famInst, Host ExportingDoor = isDoor; if (isDoor) { - if (exportType.HasUndefinedPredefinedType()) - PreDefinedType = "DOOR"; - else - PreDefinedType = exportType.ValidatedPredefinedType; + PreDefinedType = exportType.GetPredefinedTypeOrDefault("DOOR"); } ExportingWindow = isWindow; if (isWindow) { - if (exportType.HasUndefinedPredefinedType()) - PreDefinedType = "WINDOW"; - else - PreDefinedType = exportType.ValidatedPredefinedType; + PreDefinedType = exportType.GetPredefinedTypeOrDefault("WINDOW"); } FlippedSymbol = false; diff --git a/Source/Revit.IFC.Export/Utility/ElementFilteringUtil.cs b/Source/Revit.IFC.Export/Utility/ElementFilteringUtil.cs index 6857f014..26c0c9f1 100644 --- a/Source/Revit.IFC.Export/Utility/ElementFilteringUtil.cs +++ b/Source/Revit.IFC.Export/Utility/ElementFilteringUtil.cs @@ -146,54 +146,86 @@ private static ElementFilter GetDesignOptionFilter() } /// - /// Checks if element in certain category should be exported. + /// Checks if an element with a given ExportIFCCategoryInfo should be exported. /// - /// The ExporterIFC object. - /// The element. + /// The exporting mapping information for a category. + /// The optional element. /// True if IfcOpeningElement is allowed to be exported. /// True if the element should be exported, false otherwise. - private static bool ShouldCategoryBeExported(ExporterIFC exporterIFC, Element element, bool allowSeparateOpeningExport) + public static bool ShouldExportMappingInfo(ExportIFCCategoryInfo info, Element element, bool allowSeparateOpeningExport) { - IFCExportInfoPair exportType = new IFCExportInfoPair(); - ElementId categoryId; - string ifcClassName = ExporterUtil.GetIFCClassNameFromExportTable(exporterIFC, element, out categoryId); - if (string.IsNullOrEmpty(ifcClassName)) + string entityName = info?.IFCEntityName; + bool? exportFlag = info?.IFCExportFlag; + + // If the element is null, we won't do this check. If the entityName is empty, it is + // likely a sub-category that should defer to its parent to make a final decision. + if (info == null && element != null) { - // Special case: these elements aren't contained in the default export layers mapping table. - // This allows these elements to be exported by default. if (element is AreaScheme || element is Group) - ifcClassName = "IfcGroup"; + entityName = "IfcGroup"; else if (element is ElectricalSystem) - ifcClassName = "IfcSystem"; - else if (element is Grid) - ifcClassName = "IfcGrid"; // In the German template somehow the Grid does not show up in the mapping table + entityName = "IfcSystem"; else return false; - } - bool foundName = string.Compare(ifcClassName, "Default", true) != 0; - if (foundName) - exportType = GetExportTypeFromClassName(ifcClassName); - if (!foundName) - return true; + exportFlag = true; + } - if (exportType.ExportInstance == IFCEntityType.UnKnown) + if (!(exportFlag ?? false)) return false; - // We don't export openings directly, only via the element they are opening, unless flag is set. - if (exportType.ExportInstance == IFCEntityType.IfcOpeningElement && !allowSeparateOpeningExport) + if (!allowSeparateOpeningExport && (string.Compare(entityName, "IfcOpeningElement", true) == 0)) return false; - // Check whether the intended Entity type is inside the export exclusion set - IFCEntityType elementClassTypeEnum; - if (Enum.TryParse(exportType.ExportInstance.ToString(), out elementClassTypeEnum) - || Enum.TryParse(exportType.ExportType.ToString(), out elementClassTypeEnum)) - if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) + if (ExporterCacheManager.ExportOptionsCache.HasExcludeList()) + { + if (ExporterCacheManager.ExportOptionsCache.IsEntityInExcludeList(entityName)) + return false; + + IFCExportInfoPair pair = new IFCExportInfoPair(); + pair.SetByTypeName(entityName); + if (ExporterCacheManager.ExportOptionsCache.IsEntityInExcludeList(pair.ExportType.ToString())) return false; + } + return true; } + /// + /// Checks if element in certain category should be exported. + /// + /// True if IfcOpeningElement is allowed to be exported. + /// True if the element should be exported, false otherwise. + public static bool ShouldCategoryBeExported(Category category, bool allowSeparateOpeningExport) + { + ElementId categoryId = category?.Id ?? ElementId.InvalidElementId; + if (ExporterUtil.GetCategoryInfoById(categoryId, null, out ExportIFCCategoryInfo info)) + return ShouldExportMappingInfo(info, null, allowSeparateOpeningExport); + + ElementId parentCategoryId = category?.Parent?.Id ?? ElementId.InvalidElementId; + if (parentCategoryId != ElementId.InvalidElementId) + { + if (ExporterUtil.GetCategoryInfoById(parentCategoryId, null, out info)) + return ShouldExportMappingInfo(info, null, allowSeparateOpeningExport); + } + + // the category is not in the mapping template + return IsCategoryVisible(category, ExporterCacheManager.ExportOptionsCache.FilterViewForExport); + } + + /// + /// Checks if element in certain category should be exported. + /// + /// The element. + /// True if IfcOpeningElement is allowed to be exported. + /// True if the element should be exported, false otherwise. + private static bool ShouldCategoryBeExported(Element element, bool allowSeparateOpeningExport) + { + ExportIFCCategoryInfo info = ExporterUtil.GetIFCCategoryExportMappingInfo(element); + return ShouldExportMappingInfo(info, element, allowSeparateOpeningExport); + } + /// /// Checks if an element should be exported based on parameter settings. /// @@ -227,13 +259,12 @@ private static bool ShouldCategoryBeExported(ExporterIFC exporterIFC, Element el /// /// Checks if element should be exported using a variety of different checks. /// - /// The ExporterIFC object. /// The element. /// True if IfcOpeningElement is allowed to be exported. /// True if the element should be exported, false otherwise. /// There are some inefficiencies here, as we call GetExportInfoFromParameters /// in other contexts. We should attempt to get the value only once. - public static bool ShouldElementBeExported(ExporterIFC exporterIFC, Element element, bool allowSeparateOpeningExport) + public static bool ShouldElementBeExported(Element element, bool allowSeparateOpeningExport) { // Allow the ExporterStateManager to say that an element should be exported regardless of settings. if (ExporterStateManager.CanExportElementOverride) @@ -249,7 +280,7 @@ public static bool ShouldElementBeExported(ExporterIFC exporterIFC, Element elem // Check to see if the category should be exported if parameters aren't set. // Note that in previous versions, the category override the parameter settings. This is // no longer true. - if (!ShouldCategoryBeExported(exporterIFC, element, allowSeparateOpeningExport)) + if (!ShouldCategoryBeExported(element, allowSeparateOpeningExport)) return false; // Check whether the intended Entity type is inside the export exclusion set @@ -260,13 +291,12 @@ public static bool ShouldElementBeExported(ExporterIFC exporterIFC, Element elem /// /// Determines if the selected element meets extra criteria for export. /// - /// The exporter class. /// The current element to export. /// True if IfcOpeningElement is allowed to be exported. /// True if the element should be exported, false otherwise. - public static bool CanExportElement(ExporterIFC exporterIFC, Autodesk.Revit.DB.Element element, bool allowSeparateOpeningExport) + public static bool CanExportElement(Element element, bool allowSeparateOpeningExport) { - if (!ElementFilteringUtil.ShouldElementBeExported(exporterIFC, element, allowSeparateOpeningExport)) + if (!ShouldElementBeExported(element, allowSeparateOpeningExport)) return false; // if we allow exporting parts as independent building elements, then prevent also exporting the host elements containing the parts. @@ -277,56 +307,14 @@ public static bool CanExportElement(ExporterIFC exporterIFC, Autodesk.Revit.DB.E return true; } - /// - /// Checks if name is equal to base or its type name. - /// - /// The object type name. - /// The IFC base name. - /// True if equal, false otherwise. - private static bool IsEqualToTypeName(String name, String baseName) - { - if (string.Compare(name, baseName, true) == 0) - return true; - - string typeName = IfcSchemaEntityTree.GetTypeNameFromInstanceName(baseName); - return (string.Compare(name, typeName, true) == 0); - } - - /// - /// Compares two strings, ignoring spaces, punctuation and case. - /// - /// The string to compare. - /// String to compare to, all caps, no punctuation or cases. - /// - private static bool CompareAlphaOnly(String name, String baseNameAllCapsNoSpaces) - { - if (string.IsNullOrEmpty(name)) - return string.IsNullOrEmpty(baseNameAllCapsNoSpaces); - string nameToUpper = name.ToUpper(); - int loc = 0; - int maxLen = baseNameAllCapsNoSpaces.Length; - foreach (char c in nameToUpper) - { - if (c >= 'A' && c <= 'Z') - { - if (baseNameAllCapsNoSpaces[loc] != c) - return false; - loc++; - if (loc == maxLen) - return true; - } - } - return false; - } - - static IDictionary PreIFC4Remap = new Dictionary() + static readonly Dictionary PreIFC4Remap = new Dictionary() { { "IFCAUDIOVISUALAPPLIANCE", IFCEntityType.IfcElectricApplianceType }, { "IFCBURNER", IFCEntityType.IfcGasTerminalType }, { "IFCELECTRICDISTRIBUTIONBOARD", IFCEntityType.IfcElectricDistributionPoint } }; - static IDictionary IFC4Remap = new Dictionary() + static readonly Dictionary IFC4Remap = new Dictionary() { { "IFCGASTERMINAL", IFCEntityType.IfcBurnerType }, { "IFCELECTRICDISTRIBUTIONPOINT", IFCEntityType.IfcElectricDistributionBoardType }, @@ -338,7 +326,7 @@ private static bool CompareAlphaOnly(String name, String baseNameAllCapsNoSpaces /// /// The IFC class name. /// The export type. - public static IFCExportInfoPair GetExportTypeFromClassName(String originalIFCClassName) + public static IFCExportInfoPair GetExportTypeFromClassName(string originalIFCClassName) { IFCExportInfoPair exportInfoPair = new IFCExportInfoPair(); @@ -347,60 +335,51 @@ public static IFCExportInfoPair GetExportTypeFromClassName(String originalIFCCla { // Here we try to catch any possible types that are missing above by checking both the class name or the type name // Unless there is any special treatment needed most of the above check can be done here - string clName = cleanIFCClassName.Substring(cleanIFCClassName.Length - 4, 4).Equals("Type", StringComparison.CurrentCultureIgnoreCase) ? - cleanIFCClassName.Substring(0, cleanIFCClassName.Length - 4) : - cleanIFCClassName; - + string clName = cleanIFCClassName.EndsWith("TYPE") ? + cleanIFCClassName.Substring(0, cleanIFCClassName.Length - 4) : cleanIFCClassName; + // Deal with small number of IFC2x3/IFC4 types that have changed in a hardwired way. if (ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4) { if (PreIFC4Remap.TryGetValue(clName, out IFCEntityType ifcEntityType)) - exportInfoPair.SetValueWithPair(ifcEntityType); + exportInfoPair.SetByType(ifcEntityType); else - exportInfoPair.SetValueWithPair(clName); + exportInfoPair.SetByTypeName(clName); } else { if (IFC4Remap.TryGetValue(clName, out IFCEntityType ifcEntityType)) - exportInfoPair.SetValueWithPair(ifcEntityType); + exportInfoPair.SetByType(ifcEntityType); else - exportInfoPair.SetValueWithPair(clName); + exportInfoPair.SetByTypeName(clName); } if (exportInfoPair.ExportInstance == IFCEntityType.UnKnown) - exportInfoPair.SetValueWithPair(IFCEntityType.IfcBuildingElementProxy); + exportInfoPair.SetByType(IFCEntityType.IfcBuildingElementProxy); } - exportInfoPair.ValidatedPredefinedType = IFCValidateEntry.GetValidIFCPredefinedType("NOTDEFINED", exportInfoPair.ExportType.ToString()); + exportInfoPair.PredefinedType = null; return exportInfoPair; } - static IDictionary s_CategoryToExportType = null; - - static void InitializeCategoryToExportType() - { - if (s_CategoryToExportType != null) - return; - - s_CategoryToExportType = new Dictionary() { - { new ElementId(BuiltInCategory.OST_Cornices), new IFCExportInfoPair(IFCEntityType.IfcBeam, "NOTDEFINED") }, - { new ElementId(BuiltInCategory.OST_Ceilings), new IFCExportInfoPair(IFCEntityType.IfcCovering, "NOTDEFINED") }, - { new ElementId(BuiltInCategory.OST_CurtainWallPanels), new IFCExportInfoPair(IFCEntityType.IfcPlate, "CURTAIN_PANEL") }, - { new ElementId(BuiltInCategory.OST_Furniture), new IFCExportInfoPair(IFCEntityType.IfcFurniture, "NOTDEFINED") }, - { new ElementId(BuiltInCategory.OST_Floors), new IFCExportInfoPair(IFCEntityType.IfcSlab, "FLOOR") }, - { new ElementId(BuiltInCategory.OST_IOSModelGroups), new IFCExportInfoPair(IFCEntityType.IfcGroup, "NOTDEFINED") }, - { new ElementId(BuiltInCategory.OST_Mass), new IFCExportInfoPair(IFCEntityType.IfcBuildingElementProxy, "NOTDEFINED") }, - { new ElementId(BuiltInCategory.OST_CurtainWallMullions), new IFCExportInfoPair(IFCEntityType.IfcMember, "MULLION") }, - { new ElementId(BuiltInCategory.OST_Railings), new IFCExportInfoPair(IFCEntityType.IfcRailing, "NOTDEFINED") }, - { new ElementId(BuiltInCategory.OST_Ramps), new IFCExportInfoPair(IFCEntityType.IfcRamp, "NOTDEFINED") }, - { new ElementId(BuiltInCategory.OST_Roofs), new IFCExportInfoPair(IFCEntityType.IfcRoof, "NOTDEFINED") }, - { new ElementId(BuiltInCategory.OST_Site), new IFCExportInfoPair(IFCEntityType.IfcSite, "NOTDEFINED") }, - { new ElementId(BuiltInCategory.OST_Stairs), new IFCExportInfoPair(IFCEntityType.IfcStair, "NOTDEFINED") }, - { new ElementId(BuiltInCategory.OST_Walls), new IFCExportInfoPair(IFCEntityType.IfcWall, "NOTDEFINED") }, - { new ElementId(BuiltInCategory.OST_Windows), new IFCExportInfoPair(IFCEntityType.IfcWindow, "NOTDEFINED") } - }; - } + static readonly Dictionary CategoryToExportType = new Dictionary() { + { BuiltInCategory.OST_Cornices, (IFCEntityType.IfcBeam, "NOTDEFINED") }, + { BuiltInCategory.OST_Ceilings, (IFCEntityType.IfcCovering, "NOTDEFINED") }, + { BuiltInCategory.OST_CurtainWallPanels, (IFCEntityType.IfcPlate, "CURTAIN_PANEL") }, + { BuiltInCategory.OST_Furniture, (IFCEntityType.IfcFurniture, "NOTDEFINED") }, + { BuiltInCategory.OST_Floors, (IFCEntityType.IfcSlab, "FLOOR") }, + { BuiltInCategory.OST_IOSModelGroups, (IFCEntityType.IfcGroup, "NOTDEFINED") }, + { BuiltInCategory.OST_Mass, (IFCEntityType.IfcBuildingElementProxy, "NOTDEFINED") }, + { BuiltInCategory.OST_CurtainWallMullions, (IFCEntityType.IfcMember, "MULLION") }, + { BuiltInCategory.OST_Railings, (IFCEntityType.IfcRailing, "NOTDEFINED") }, + { BuiltInCategory.OST_Ramps, (IFCEntityType.IfcRamp, "NOTDEFINED") }, + { BuiltInCategory.OST_Roofs, (IFCEntityType.IfcRoof, "NOTDEFINED") }, + { BuiltInCategory.OST_Site, (IFCEntityType.IfcSite, "NOTDEFINED") }, + { BuiltInCategory.OST_Stairs, (IFCEntityType.IfcStair, "NOTDEFINED") }, + { BuiltInCategory.OST_Walls, (IFCEntityType.IfcWall, "NOTDEFINED") }, + { BuiltInCategory.OST_Windows, (IFCEntityType.IfcWindow, "NOTDEFINED") } + }; /// /// Gets export type from category id. @@ -409,10 +388,10 @@ static void InitializeCategoryToExportType() /// The export type. public static IFCExportInfoPair GetExportTypeFromCategoryId(ElementId categoryId) { - InitializeCategoryToExportType(); - IFCExportInfoPair exportInfoPair; - if (s_CategoryToExportType.TryGetValue(categoryId, out exportInfoPair)) - return exportInfoPair; + (IFCEntityType, string) exportInfoPair; + BuiltInCategory builtInCategory = (BuiltInCategory)categoryId.Value; + if (CategoryToExportType.TryGetValue(builtInCategory, out exportInfoPair)) + return new IFCExportInfoPair(exportInfoPair.Item1, exportInfoPair.Item2); return new IFCExportInfoPair(); } @@ -425,11 +404,13 @@ private static ElementFilter GetViewSpecificTypesFilter(ExporterIFC exporter) { ElementFilter ownerViewFilter = GetOwnerViewFilter(exporter); - List viewSpecificTypes = new List(); - viewSpecificTypes.Add(typeof(TextNote)); - viewSpecificTypes.Add(typeof(FilledRegion)); - ElementMulticlassFilter classFilter = new ElementMulticlassFilter(viewSpecificTypes); + List viewSpecificTypes = new List() + { + typeof(TextNote), + typeof(FilledRegion) + }; + ElementMulticlassFilter classFilter = new ElementMulticlassFilter(viewSpecificTypes); LogicalAndFilter viewSpecificTypesFilter = new LogicalAndFilter(ownerViewFilter, classFilter); return viewSpecificTypesFilter; @@ -467,89 +448,102 @@ private static ElementFilter GetClassFilter(bool forSpatialElements) } else { - List excludedTypes = new List(); - - // FamilyInstances are handled in separate filter. - excludedTypes.Add(typeof(FamilyInstance)); - - // Spatial element are exported in a separate pass. - excludedTypes.Add(typeof(SpatialElement)); - - // AreaScheme elements are exported as groups after all Areas have been exported. - excludedTypes.Add(typeof(AreaScheme)); - // FabricArea elements are exported as groups after all FabricSheets have been exported. - excludedTypes.Add(typeof(FabricArea)); - - if (!ExporterCacheManager.ExportOptionsCache.ExportAnnotations) - excludedTypes.Add(typeof(CurveElement)); - - excludedTypes.Add(typeof(ElementType)); - - excludedTypes.Add(typeof(BaseArray)); - - excludedTypes.Add(typeof(FillPatternElement)); - excludedTypes.Add(typeof(LinePatternElement)); - excludedTypes.Add(typeof(Material)); - excludedTypes.Add(typeof(GraphicsStyle)); - excludedTypes.Add(typeof(Family)); - excludedTypes.Add(typeof(SketchPlane)); - excludedTypes.Add(typeof(View)); - excludedTypes.Add(typeof(Autodesk.Revit.DB.Structure.LoadBase)); - - // curtain wall sub-types we are ignoring. - excludedTypes.Add(typeof(CurtainGridLine)); - // excludedTypes.Add(typeof(Mullion)); - - // this will be gotten from the element(s) it cuts. - excludedTypes.Add(typeof(Opening)); - - // 2D types we are ignoring - excludedTypes.Add(typeof(SketchBase)); - excludedTypes.Add(typeof(FaceSplitter)); - - // 2D types covered by the element owner view filter - excludedTypes.Add(typeof(TextNote)); - excludedTypes.Add(typeof(FilledRegion)); - - // exclude levels that are covered in BeginExport - excludedTypes.Add(typeof(Level)); - - // exclude analytical models - excludedTypes.Add(typeof(Autodesk.Revit.DB.Structure.AnalyticalElement)); - ElementFilter excludedClassFilter = new ElementMulticlassFilter(excludedTypes, true); - - List excludedCategories = new List(); - - // Native Revit types without match in API - excludedCategories.Add(BuiltInCategory.OST_ConduitCenterLine); - excludedCategories.Add(BuiltInCategory.OST_ConduitFittingCenterLine); - excludedCategories.Add(BuiltInCategory.OST_DecalElement); - //excludedCategories.Add(BuiltInCategory.OST_Parts); - //excludedCategories.Add(BuiltInCategory.OST_RvtLinks); - excludedCategories.Add(BuiltInCategory.OST_DuctCurvesCenterLine); - excludedCategories.Add(BuiltInCategory.OST_DuctFittingCenterLine); - excludedCategories.Add(BuiltInCategory.OST_FlexDuctCurvesCenterLine); - excludedCategories.Add(BuiltInCategory.OST_FlexPipeCurvesCenterLine); - excludedCategories.Add(BuiltInCategory.OST_IOS_GeoLocations); - excludedCategories.Add(BuiltInCategory.OST_PipeCurvesCenterLine); - excludedCategories.Add(BuiltInCategory.OST_PipeFittingCenterLine); - excludedCategories.Add(BuiltInCategory.OST_Property); - excludedCategories.Add(BuiltInCategory.OST_SiteProperty); - excludedCategories.Add(BuiltInCategory.OST_SitePropertyLineSegment); - excludedCategories.Add(BuiltInCategory.OST_TopographyContours); - excludedCategories.Add(BuiltInCategory.OST_Viewports); - excludedCategories.Add(BuiltInCategory.OST_Views); - - // Exclude elements with no category. - excludedCategories.Add(BuiltInCategory.INVALID); - - ElementMulticategoryFilter excludedCategoryFilter = new ElementMulticategoryFilter(excludedCategories, true); - - LogicalAndFilter exclusionFilter = new LogicalAndFilter(excludedClassFilter, excludedCategoryFilter); - - ElementOwnerViewFilter ownerViewFilter = new ElementOwnerViewFilter(ElementId.InvalidElementId); - - LogicalAndFilter returnedFilter = new LogicalAndFilter(exclusionFilter, ownerViewFilter); + List excludedTypes = new List + { + typeof(AnalyticalElement), + + // AreaScheme elements are exported as groups after all Areas have been + // exported. + typeof(AreaScheme), + + // curtain wall sub-types we are ignoring. + typeof(CurtainGridLine), + // typeof(Mullion), + + typeof(ElevationMarker), + + // FabricArea elements are exported as groups after all FabricSheets have + // been exported. + typeof(FabricArea), + + // exclude levels that are covered in BeginExport + typeof(Level), + + // this will be gotten from the element(s) it cuts. + typeof(Opening), + + // Spatial element are exported in a separate pass. + typeof(SpatialElement), + + // 2D types we are ignoring + typeof(FaceSplitter), + typeof(Revision), + typeof(SketchBase), + + // 2D types covered by the element owner view filter + typeof(FilledRegion), + typeof(TextNote), + + typeof(BaseArray), + typeof(ColorFillScheme), + typeof(ElementType), + typeof(GraphicsStyle), + typeof(Family), + typeof(FamilyInstance), + typeof(FillPatternElement), + typeof(InternalOrigin), + typeof(LinePatternElement), + typeof(LoadBase), + typeof(LoadCase), + typeof(Material), + typeof(Phase), + typeof(SketchPlane), + typeof(SunAndShadowSettings), + typeof(View) + }; + + ElementFilter excludedClassFilter = new ElementMulticlassFilter(excludedTypes, + true); + + List excludedCategories = new List() + { + // Native Revit types without match in API + BuiltInCategory.OST_ConduitCenterLine, + BuiltInCategory.OST_ConduitFittingCenterLine, + BuiltInCategory.OST_DecalElement, + //BuiltInCategory.OST_Parts, + //BuiltInCategory.OST_RvtLinks, + BuiltInCategory.OST_DuctCurvesCenterLine, + BuiltInCategory.OST_DuctFittingCenterLine, + BuiltInCategory.OST_FlexDuctCurvesCenterLine, + BuiltInCategory.OST_FlexPipeCurvesCenterLine, + BuiltInCategory.OST_HVAC_Load_Schedules, + BuiltInCategory.OST_IOS_GeoLocations, + BuiltInCategory.OST_IOSSketchGrid, + BuiltInCategory.OST_PipeCurvesCenterLine, + BuiltInCategory.OST_PipeFittingCenterLine, + BuiltInCategory.OST_Property, + BuiltInCategory.OST_SitePropertyLineSegment, + BuiltInCategory.OST_TopographyContours, + BuiltInCategory.OST_Viewers, + BuiltInCategory.OST_Viewports, + BuiltInCategory.OST_Views, + + // Exclude elements with no category. + BuiltInCategory.INVALID + }; + + ElementMulticategoryFilter excludedCategoryFilter = + new ElementMulticategoryFilter(excludedCategories, true); + + LogicalAndFilter exclusionFilter = new LogicalAndFilter(excludedClassFilter, + excludedCategoryFilter); + + ElementOwnerViewFilter ownerViewFilter = + new ElementOwnerViewFilter(ElementId.InvalidElementId); + + LogicalAndFilter returnedFilter = new LogicalAndFilter(exclusionFilter, + ownerViewFilter); return returnedFilter; } @@ -658,7 +652,7 @@ public static bool IsElementVisible(Element element) if (hidden) return false; - Category category = element.Category; + Category category = CategoryUtil.GetSafeCategory(element); hidden = !IsCategoryVisible(category, filterView); if (hidden) return false; diff --git a/Source/Revit.IFC.Export/Utility/ElementTypeToHandleCache.cs b/Source/Revit.IFC.Export/Utility/ElementTypeToHandleCache.cs index f442c459..053ad503 100644 --- a/Source/Revit.IFC.Export/Utility/ElementTypeToHandleCache.cs +++ b/Source/Revit.IFC.Export/Utility/ElementTypeToHandleCache.cs @@ -1,7 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; using Autodesk.Revit.DB; using Autodesk.Revit.DB.IFC; using Revit.IFC.Common.Enums; @@ -14,7 +12,7 @@ namespace Revit.IFC.Export.Utility /// public sealed class ElementTypeKey : Tuple { - public ElementTypeKey(ElementType elementType, IFCEntityType entType, string preDefinedType) : base(elementType, entType, preDefinedType) { } + public ElementTypeKey(ElementType elementType, IFCExportInfoPair exportAs) : base(elementType, exportAs.ExportType, exportAs.GetPredefinedTypeOrDefault()) { } } /// @@ -89,7 +87,7 @@ public class ElementTypeToHandleCache public IFCAnyHandle Find(ElementType elementType, IFCExportInfoPair exportType) { IFCAnyHandle handle; - var key = new ElementTypeKey(elementType, exportType.ExportType, exportType.ValidatedPredefinedType); + var key = new ElementTypeKey(elementType, exportType); if (m_ElementTypeToHandleDictionary.TryGetValue(key, out handle)) { return handle; @@ -161,7 +159,7 @@ public void RemoveInvalidHandles(ISet keys) /// public void Register(ElementType elementType, IFCExportInfoPair exportType, IFCAnyHandle handle) { - var key = new ElementTypeKey(elementType, exportType.ExportType, exportType.ValidatedPredefinedType); + var key = new ElementTypeKey(elementType, exportType); if (m_ElementTypeToHandleDictionary.ContainsKey(key) || exportType.ExportType == IFCEntityType.UnKnown) return; diff --git a/Source/Revit.IFC.Export/Utility/ExportOptionsCache.cs b/Source/Revit.IFC.Export/Utility/ExportOptionsCache.cs index e2c790ae..7f1e68ff 100644 --- a/Source/Revit.IFC.Export/Utility/ExportOptionsCache.cs +++ b/Source/Revit.IFC.Export/Utility/ExportOptionsCache.cs @@ -73,8 +73,22 @@ public IFCFileHeaderItem FileHeaderItem } } + /// + /// Always export floors and roofs as a single entity unless exporting parts. + /// + public bool ExportHostAsSingleEntity { get; private set; } = false; + + /// + /// If set, set the IfcOwnerHistory LastModified attribute to be the Author in Project Information. + /// + public bool OwnerHistoryLastModified { get; private set; } = false; + public KnownERNames ExchangeRequirement { get; set; } = KnownERNames.NotDefined; + public KnownFacilityTypes FacilityType { get; set; } = KnownFacilityTypes.Building; + + public string FacilityPredefinedType { get; set; } = null; + public string GeoRefCRSName { get; private set; } public string GeoRefCRSDesc { get; private set; } @@ -250,7 +264,8 @@ public static ExportOptionsCache Create(ExporterIFC exporterIFC, View filterView ExportOptionsCache cache = new ExportOptionsCache(); cache.FileVersion = exporterIFC.FileVersion; - cache.FileName = exporterIFC.FileName; + cache.FullFileName = exporterIFC.FileName; + cache.FileNameOnly = Path.GetFileName(cache.FullFileName); cache.ExportBaseQuantities = exporterIFC.ExportBaseQuantities; cache.WallAndColumnSplitting = exporterIFC.WallAndColumnSplitting; cache.SpaceBoundaryLevel = exporterIFC.SpaceBoundaryLevel; @@ -298,6 +313,21 @@ public static ExportOptionsCache Create(ExporterIFC exporterIFC, View filterView bool? exportAdvancedSweptSolids = OptionsUtil.GetNamedBooleanOption(options, "ExportAdvancedSweptSolids"); cache.ExportAdvancedSweptSolids = (exportAdvancedSweptSolids.HasValue) ? exportAdvancedSweptSolids.Value : false; + string exchangeRequirementString = OptionsUtil.GetNamedStringOption(options, "ExchangeRequirement"); + if (Enum.TryParse(exchangeRequirementString, out KnownERNames exchangeRequirment)) + { + cache.ExchangeRequirement = exchangeRequirment; + } + + string facilityTypeString = OptionsUtil.GetNamedStringOption(options, "FacilityType"); + if (Enum.TryParse(facilityTypeString, out KnownFacilityTypes facilityType) && + facilityType != KnownFacilityTypes.NotDefined) + { + cache.FacilityType = facilityType; + } + + cache.FacilityPredefinedType = OptionsUtil.GetNamedStringOption(options, "FacilityPredefinedType"); + // Set GUIDOptions here. { // This option should be rarely used, and is only for consistency with old files. As such, it is set by environment variable only. @@ -329,6 +359,12 @@ public static ExportOptionsCache Create(ExporterIFC exporterIFC, View filterView (useOnlyTypeNameForIfcType != null) && useOnlyTypeNameForIfcType.GetValueOrDefault(); } + bool? exportHostAsSingleEntity = OptionsUtil.GetNamedBooleanOption(options, "ExportHostAsSingleEntity"); + cache.ExportHostAsSingleEntity = exportHostAsSingleEntity.GetValueOrDefault(false); + + bool? ownerHistoryLastModified = OptionsUtil.GetNamedBooleanOption(options, "OwnerHistoryLastModified"); + cache.OwnerHistoryLastModified = ownerHistoryLastModified.GetValueOrDefault(false); + // "SingleElement" export option - useful for debugging - only one input element will be processed for export if (options.TryGetValue("SingleElement", out string singleElementValue)) { @@ -408,7 +444,9 @@ public static ExportOptionsCache Create(ExporterIFC exporterIFC, View filterView if (options.TryGetValue("ActivePhaseId", out activePhaseElementValue)) cache.ActivePhaseId = ParseElementId(activePhaseElementValue); - if ((cache.ActivePhaseId == ElementId.InvalidElementId) && (cache.FilterViewForExport != null)) + // If we have a filter view, the phase to be exported is only the phase of the + // view. So we ignore any phase sent. + if (cache.FilterViewForExport != null) { Parameter currPhase = cache.FilterViewForExport.get_Parameter(BuiltInParameter.VIEW_PHASE); if (currPhase != null) @@ -422,6 +460,8 @@ public static ExportOptionsCache Create(ExporterIFC exporterIFC, View filterView cache.SelectedParametermappingTableName = OptionsUtil.GetNamedStringOption(options, "ExportUserDefinedParameterMappingFileName"); + cache.CategoryMappingTableName = OptionsUtil.GetNamedStringOption(options, "CategoryMapping"); + // This is for the option to export links as part of a federated export. string federatedInfoString = OptionsUtil.GetNamedStringOption(options, "FederatedLinkInfo"); cache.FederatedLinkInfo = ParseFederatedLinkInfo(federatedInfoString); @@ -563,13 +603,13 @@ private static void ParseFileType(IDictionary options, ExportOpt throw new Exception("Option 'FileType' did not match an existing IFCFileFormat value"); } } - else if (!string.IsNullOrEmpty(cache.FileName)) + else if (!string.IsNullOrEmpty(cache.FileNameOnly)) { - if (cache.FileName.EndsWith(".ifcXML")) //localization? + if (cache.FileNameOnly.EndsWith(".ifcXML")) //localization? { cache.IFCFileFormat = IFCFileFormat.IfcXML; } - else if (cache.FileName.EndsWith(".ifcZIP")) + else if (cache.FileNameOnly.EndsWith(".ifcZIP")) { cache.IFCFileFormat = IFCFileFormat.IfcZIP; } @@ -597,13 +637,14 @@ public PropertySetOptions PropertySetOptions public IFCVersion FileVersion { get; set; } /// - /// The file name. + /// The full file name, including path. /// - public string FileName - { - get; - set; - } + public string FullFileName { get; set; } + + /// + /// The file name, not the including path. + /// + public string FileNameOnly { get; set; } /// /// Identifies if the schema version being exported is IFC 2x2. @@ -985,39 +1026,23 @@ public bool Use2DRoomBoundaryForRoomVolumeCreation /// /// Contains options for setting how entity names are generated. /// - public NamingOptions NamingOptions - { - get; - set; - } + public NamingOptions NamingOptions { get; set; } /// /// The file format to export. Not used currently. /// // TODO: Connect this to the output file being written by the client. - public IFCFileFormat IFCFileFormat - { - get; - set; - } + public IFCFileFormat IFCFileFormat { get; set; } /// /// Select export Config Name from the UI /// - public String SelectedConfigName - { - get; - set; - } + public string SelectedConfigName { get; set; } /// /// Select export Config Name from the UI /// - public String SelectedParametermappingTableName - { - get; - set; - } + public string SelectedParametermappingTableName { get; set; } /// /// Allow exporting a mix of extrusions and BReps as a solid model, if possible. @@ -1027,20 +1052,12 @@ public String SelectedParametermappingTableName /// /// Specifies which phase id to export. May be expanded to phases. /// - public ElementId ActivePhaseId - { - get; - protected set; - } + public ElementId ActivePhaseId { get; protected set; } /// /// The phase element corresponding to the phase id. /// - public Phase ActivePhaseElement - { - get; - protected set; - } + public Phase ActivePhaseElement { get; protected set; } /// /// The status of how to handle Revit link instances. @@ -1056,6 +1073,12 @@ public bool ExportingSeparateLink() return ExportLinkedFileAs == LinkedFileExportAs.ExportAsSeparate; } + /// + /// The table that contains Revit class to IFC entity mappings. + /// + public string CategoryMappingTableName { get; set; } = null; + + private IList> LinkInstanceInfos { get; } = new List>(); /// @@ -1128,7 +1151,26 @@ public View ActiveView /// true if the entity found in the set public bool IsElementInExcludeList(IFCEntityType entity) { - return (ExcludeElementSet.Contains(entity.ToString())); + return IsEntityInExcludeList(entity.ToString()); + } + + /// + /// To check whether a specified IFC Entity is listed in the Exclude Filter (from configuration) + /// + /// IFCEntityType enumeration representing the IFC entity concerned + /// true if the entity found in the set + public bool IsEntityInExcludeList(string entityTypeName) + { + return ExcludeElementSet.Contains(entityTypeName); + } + + /// + /// Check whether there is an Exclude Filter (from configuration) + /// + /// True if there are any entities excluded. + public bool HasExcludeList() + { + return ExcludeElementSet.Count > 0; } /// @@ -1148,8 +1190,13 @@ HashSet ExcludeElementSet if (!string.IsNullOrEmpty(ExcludeFilter)) { string[] eList = ExcludeFilter.Split(';'); - foreach (string elem in eList) - exclSet.Add(elem); + foreach (string entityToFilter in eList) + { + if (!string.IsNullOrWhiteSpace(entityToFilter)) + { + exclSet.Add(entityToFilter); + } + } } _excludesElementSet = exclSet; return _excludesElementSet; diff --git a/Source/Revit.IFC.Export/Utility/ExporterCacheManager.cs b/Source/Revit.IFC.Export/Utility/ExporterCacheManager.cs index 168d3442..033718c8 100644 --- a/Source/Revit.IFC.Export/Utility/ExporterCacheManager.cs +++ b/Source/Revit.IFC.Export/Utility/ExporterCacheManager.cs @@ -27,8 +27,6 @@ using Revit.IFC.Export.Toolkit; using Revit.IFC.Export.Exporter.PropertySet; using Revit.IFC.Common.Enums; -using System.Runtime.Remoting.Contexts; -using System.Runtime.InteropServices.WindowsRuntime; using Revit.IFC.Common.Utility; namespace Revit.IFC.Export.Utility @@ -41,7 +39,7 @@ public class ExporterCacheManager /// /// The AllocatedGeometryObjectCache object. /// - static AllocatedGeometryObjectCache m_AllocatedGeometryObjectCache; + static public AllocatedGeometryObjectCache AllocatedGeometryObjectCache { get; protected set; } = new AllocatedGeometryObjectCache(); /// /// The AssemblyInstanceCache object. @@ -60,14 +58,9 @@ public class ExporterCacheManager static IDictionary m_CanExportBeamGeometryAsExtrusionCache; /// - /// Cache the values of the IFC entity class from the IFC Export table by category. + /// Keeps track of the active ifc category mapping template. /// - static Dictionary, string> m_CategoryClassNameCache; - - /// - /// Cache the values of the IFC entity pre-defined type from the IFC Export table by category. - /// - static Dictionary, string> m_CategoryTypeCache; + static IFCCategoryTemplate m_CategoryMappingTemplate = null; /// /// The ClassificationCache object. @@ -105,6 +98,12 @@ public class ExporterCacheManager /// static ElementToHandleCache m_ElementToHandleCache; + /// + /// A mapping of element ids to a material id determined by looking at element parameters. + /// + static public IDictionary ElementIdMaterialParameterCache { get; set; } = + new Dictionary(); + /// /// The ElementTypeToHandleCache cache /// @@ -112,6 +111,11 @@ public class ExporterCacheManager static IDictionary m_FabricParamsCache; + /// + /// The ExporterIFC used to access internal IFC API functions. + /// + static public ExporterIFC ExporterIFC { get; set; } = null; + /// /// The ExportOptions cache. /// @@ -479,6 +483,11 @@ public static IFCAnyHandle Get2DContextHandle(IFCRepresentationIdentifier identi /// static public IDictionary> ComplexPropertyCache { get; set; } = new Dictionary>(); + /// + /// Cache for Base Quantities that require separate calculation. + /// + static public IDictionary> BaseQuantitiesCache { get; set; } = new Dictionary>(); + /// /// Cache for the Project Location that comes from the Selected Site on export option /// @@ -488,19 +497,6 @@ public static IFCAnyHandle Get2DContextHandle(IFCRepresentationIdentifier identi /// static public HashSet<(IFCAnyHandle, string)> QtoSetCreated { get; set; } = new HashSet<(IFCAnyHandle, string)>(); - /// - /// The AllocatedGeometryObjectCache object. - /// - public static AllocatedGeometryObjectCache AllocatedGeometryObjectCache - { - get - { - if (m_AllocatedGeometryObjectCache == null) - m_AllocatedGeometryObjectCache = new AllocatedGeometryObjectCache(); - return m_AllocatedGeometryObjectCache; - } - } - /// /// The AssemblyInstanceCache object. /// @@ -528,29 +524,35 @@ public static AssemblyInstanceCache AssemblyInstanceCache } } - /// - /// The CategoryClassNameCache object. - /// - public static IDictionary, string> CategoryClassNameCache + public static IFCCategoryTemplate CategoryMappingTemplate { get { - if (m_CategoryClassNameCache == null) - m_CategoryClassNameCache = new Dictionary, string>(); - return m_CategoryClassNameCache; - } - } + // TODO: this isn't really correct if we are exporting multiple documents. + if (m_CategoryMappingTemplate == null) + { + try + { + string name = ExportOptionsCache.CategoryMappingTableName; + if (name != null) + { + Document document = ExportOptionsCache.HostDocument ?? Document; + m_CategoryMappingTemplate = IFCCategoryTemplate.FindByName(document, name); + } + } + catch + { + m_CategoryMappingTemplate = null; + } + + if (m_CategoryMappingTemplate == null) + { + m_CategoryMappingTemplate = IFCCategoryTemplate.GetOrCreateInSessionTemplate(Document); + } + m_CategoryMappingTemplate?.UpdateCategoryList(Document); + } - /// - /// The CategoryTypeCache object. - /// - public static IDictionary, string> CategoryTypeCache - { - get - { - if (m_CategoryTypeCache == null) - m_CategoryTypeCache = new Dictionary, string>(); - return m_CategoryTypeCache; + return m_CategoryMappingTemplate; } } @@ -1491,9 +1493,12 @@ public static void Clear(bool fullClear) { if (fullClear) { + m_CategoryMappingTemplate = null; m_CertifiedEntitiesAndPsetCache = null; + ExporterIFC = null; m_ExportOptionsCache = null; m_Global3DOriginHandle = null; + Context2DHandles.Clear(); Context3DHandles.Clear(); GUIDCache.Clear(); OwnerHistoryHandle = null; @@ -1509,24 +1514,21 @@ public static void Clear(bool fullClear) SiteHandle = null; } - if (m_AllocatedGeometryObjectCache != null) - m_AllocatedGeometryObjectCache.DisposeCache(); + AllocatedGeometryObjectCache.DisposeCache(); ParameterUtil.ClearParameterValueCaches(); - m_AllocatedGeometryObjectCache = null; m_AreaSchemeCache = null; m_AssemblyInstanceCache = null; BaseLinkedDocumentGUID = null; m_BeamSystemCache = null; BuildingHandle = null; m_CanExportBeamGeometryAsExtrusionCache = null; - m_CategoryClassNameCache = null; - m_CategoryTypeCache = null; m_CeilingSpaceRelCache = null; m_ClassificationCache = null; m_ClassificationLocationCache = null; ContainmentCache = new ContainmentCache(); ComplexPropertyCache.Clear(); + BaseQuantitiesCache.Clear(); m_CreatedInternalPropertySets = null; m_CreatedSpecialPropertySets = null; m_CurveAnnotationCache = null; @@ -1535,6 +1537,7 @@ public static void Clear(bool fullClear) m_DoorWindowDelayedOpeningCreatorCache = null; m_DummyHostCache = null; m_ElementsInAssembliesCache = null; + ElementIdMaterialParameterCache.Clear(); m_ElementToHandleCache = null; m_ElementTypeToHandleCache = null; m_FabricAreaHandleCache = null; @@ -1549,7 +1552,7 @@ public static void Clear(bool fullClear) m_HostPartsCache = null; m_InternallyCreatedRootHandles = null; m_IsExternalParameterValueCache = null; - LevelInfoCache = new LevelInfoCache(); + LevelInfoCache.Clear(ExporterIFC); m_MaterialIdToStyleHandleCache = null; MaterialSetUsageCache = new MaterialSetUsageCache(); m_MaterialSetCache = null; diff --git a/Source/Revit.IFC.Export/Utility/ExporterUtil.cs b/Source/Revit.IFC.Export/Utility/ExporterUtil.cs index 6c2d4487..f7acf557 100644 --- a/Source/Revit.IFC.Export/Utility/ExporterUtil.cs +++ b/Source/Revit.IFC.Export/Utility/ExporterUtil.cs @@ -26,9 +26,9 @@ using Revit.IFC.Export.Exporter; using Revit.IFC.Export.Exporter.PropertySet; using Revit.IFC.Export.Toolkit; -using Revit.IFC.Export.Utility; using Revit.IFC.Common.Utility; using Revit.IFC.Common.Enums; +using Autodesk.Revit.DB.Structure; namespace Revit.IFC.Export.Utility { @@ -396,9 +396,9 @@ public static IFCAnyHandle CreateCartesianPoint(IFCFile file, IList meas double ceilMeasure = Math.Ceiling(value); double floorMeasure = Math.Floor(value); - if (MathUtil.IsAlmostEqual(value, ceilMeasure)) + if (MathUtil.IsAlmostZero(value - ceilMeasure)) cleanMeasure.Add(ceilMeasure); - else if (MathUtil.IsAlmostEqual(value, floorMeasure)) + else if (MathUtil.IsAlmostZero(value - floorMeasure)) cleanMeasure.Add(floorMeasure); else cleanMeasure.Add(value); @@ -748,71 +748,176 @@ public static IList CopyRepresentations(ExporterIFC exporterIFC, E IFCAnyHandleUtil.GetProductDefinitionShapeDescription(origProductDefinitionShape), representations); } - private static string GetIFCClassNameFromExportTable(ExporterIFC exporterIFC, Element element, ElementId categoryId, int specialClassId) + /// + /// Get the mapping information for a particular category and wall function. + /// + /// The category id. + /// The optional wall function. + /// The mapping information for the category if it exists. + /// + public static bool GetCategoryInfoById(ElementId categoryId, WallFunction? wallFunction, + out ExportIFCCategoryInfo info) { - if (element == null) - return null; + CustomSubCategoryId customSubCategoryId = WallFunctionToCustomSubCategoryId(wallFunction); + info = ExporterCacheManager.CategoryMappingTemplate.GetMappingInfoById(ExporterCacheManager.Document, categoryId, customSubCategoryId); + return !(info?.IsDefault() ?? true); + } - KeyValuePair key = new KeyValuePair(categoryId, specialClassId); - string ifcClassName = null; - if (!ExporterCacheManager.CategoryClassNameCache.TryGetValue(key, out ifcClassName)) + /// + /// Converts WallFunction enum to IFC CustomSubCategoryId + /// + /// Optional wall function. + /// The custom sub-category id. + public static CustomSubCategoryId WallFunctionToCustomSubCategoryId(WallFunction? wallFunction) + { + CustomSubCategoryId specialType = CustomSubCategoryId.None; + if (wallFunction == null) + return specialType; + + switch (wallFunction) { - ifcClassName = ExporterIFCUtils.GetIFCClassName(element, exporterIFC); - ExporterCacheManager.CategoryClassNameCache[key] = ifcClassName; + case WallFunction.Coreshaft: specialType = CustomSubCategoryId.Coreshaft; break; + case WallFunction.Exterior: specialType = CustomSubCategoryId.ExteriorWall; break; + case WallFunction.Foundation: specialType = CustomSubCategoryId.FoundationWall; break; + case WallFunction.Interior: specialType = CustomSubCategoryId.InteriorWall; break; + case WallFunction.Retaining: specialType = CustomSubCategoryId.RetainingWall; break; + case WallFunction.Soffit: specialType = CustomSubCategoryId.Soffit; break; } + return specialType; + } - return ifcClassName; + private static string GetIFCEntityNameFromExportTable(WallFunction wallFunction) + { + if (GetCategoryInfoById(new ElementId(BuiltInCategory.OST_Walls), wallFunction, + out ExportIFCCategoryInfo info)) + { + return info.IFCEntityName; + } + return null; } - private static string GetIFCTypeFromExportTable(ExporterIFC exporterIFC, Element element, ElementId categoryId, int specialClassId) + private static string GetIFCTypeFromExportTable(WallFunction wallFunction) { - if (element == null) - return null; + if (GetCategoryInfoById(new ElementId(BuiltInCategory.OST_Walls), wallFunction, + out ExportIFCCategoryInfo info)) + { + return info.IFCPredefinedType; + } + return null; + } - KeyValuePair key = new KeyValuePair(categoryId, specialClassId); - string ifcType = null; - if (!ExporterCacheManager.CategoryTypeCache.TryGetValue(key, out ifcType)) + /// + /// Get the category and function information for an element. + /// + /// The element. + /// The category and the optional function + public static (Category, WallFunction?) GetMappingKeyInformationForElement(Element element) + { + // TODO: This should really return CustomSubCategoryId, which in theory could apply to more than walls. + Category category = CategoryUtil.GetSafeCategory(element); + WallFunction? wallFunction = null; + + ElementId categoryId = category?.Id ?? ElementId.InvalidElementId; + if (categoryId == new ElementId(BuiltInCategory.OST_Walls) && (element is Wall)) { - ifcType = ExporterIFCUtils.GetIFCType(element, exporterIFC); - ExporterCacheManager.CategoryTypeCache[key] = ifcType; + WallType wallType = element.Document.GetElement(element.GetTypeId()) as WallType; + if (wallType != null) + { + wallFunction = wallType.Function; + } } - return ifcType; + return (category, wallFunction); } /// - /// Get the IFC class name assigned in the export layers table for a category. Cache values to avoid calls to internal code. + /// Get the IFC category mapping information associated with an element. /// - /// The exporterIFC class. - /// The category id. - /// The entity name. - public static string GetIFCClassNameFromExportTable(ExporterIFC exporterIFC, ElementId categoryId) + /// The element. + /// The category mapping information, if found. + public static ExportIFCCategoryInfo GetIFCCategoryExportMappingInfo(Element element) { - if (categoryId == ElementId.InvalidElementId) + (Category category, WallFunction? wallFunction) = GetMappingKeyInformationForElement(element); + + ElementId categoryId = category?.Id ?? ElementId.InvalidElementId; + ExportIFCCategoryInfo info; + if (GetCategoryInfoById(categoryId, wallFunction, out info)) + { + // If the category information is default (i.e., export and ), then we try our luck + // with the parent. If the flag is false, we aren't exporting it anyway. In the future, we may + // get the parent info and override the flag, if there is value to that. + if (!info.IsDefault()) + { + return info; + } + } + + // If the wall function is not null, then the "parent" category id is the original + // category id, minus the wall function. + ElementId parentCategoryId = category?.Parent?.Id ?? (wallFunction == null ? ElementId.InvalidElementId : categoryId); + if (parentCategoryId != ElementId.InvalidElementId) + { + if (GetCategoryInfoById(parentCategoryId, null, out ExportIFCCategoryInfo parentInfo)) + { + return parentInfo; + } + } + + return info; + } + + /// + /// Get the IFC entity name assigned in the category mapping table for a particular categoy. + /// + /// The category. + /// The entity name if found. + public static string GetIFCEntityNameFromExportTable(Category category) + { + if (category == null) + { return null; + } - KeyValuePair key = new KeyValuePair(categoryId, -1); - string ifcClassName = null; - if (!ExporterCacheManager.CategoryClassNameCache.TryGetValue(key, out ifcClassName)) + if (GetCategoryInfoById(category.Id, null, out ExportIFCCategoryInfo info)) { - string ifcClassAndTypeName = ExporterIFCUtils.GetIFCClassNameByCategory(categoryId, exporterIFC); - string ifcTypeName = null; - ExportEntityAndPredefinedType(ifcClassAndTypeName, out ifcClassName, out ifcTypeName); - ExporterCacheManager.CategoryClassNameCache[key] = ifcClassName; + return info.IFCEntityName; + } - // This actually represents an error in the export layers table, where the class name and type name - // or jointly given as a class name. This worked before, though, so for now we'll allow this case - // to continue working. - if (!string.IsNullOrEmpty(ifcTypeName) && - (!ExporterCacheManager.CategoryTypeCache.ContainsKey(key) || - string.IsNullOrEmpty(ExporterCacheManager.CategoryTypeCache[key]))) - ExporterCacheManager.CategoryTypeCache[key] = ifcTypeName; + ElementId parentCategoryId = category.Parent?.Id ?? ElementId.InvalidElementId; + if (parentCategoryId != ElementId.InvalidElementId) + { + if (GetCategoryInfoById(parentCategoryId, null, out info)) + { + return info.IFCEntityName; + } } - return ifcClassName; + return null; } - private static string GetIFCClassNameOrTypeForMass(ExporterIFC exporterIFC, Element element, ElementId categoryId, bool getClassName) + /// + /// Get the IFC predefined type name assigned in the category mapping table for a particular categoy. + /// + /// The category. + /// The predefined type if found. + public static string GetIFCTypeFromExportTable(Category category) + { + if (category == null) + return null; + + if (GetCategoryInfoById(category.Id, null, out ExportIFCCategoryInfo info)) + return info.IFCPredefinedType; + + if (category.Parent != null) + { + if (GetCategoryInfoById(category.Parent.Id, null, out info)) + return info.IFCPredefinedType; + } + + return null; + } + + private static Category GetCategoryForMass(Element element) { Options geomOptions = GeometryUtil.GetIFCExportGeometryOptions(); GeometryElement geomElem = element.get_Geometry(geomOptions); @@ -820,46 +925,58 @@ private static string GetIFCClassNameOrTypeForMass(ExporterIFC exporterIFC, Elem return null; SolidMeshGeometryInfo solidMeshCapsule = GeometryUtil.GetSplitSolidMeshGeometry(geomElem); - IList solidInfos = solidMeshCapsule.GetSolidInfos(); + IList solidInfos = solidMeshCapsule.SolidInfoList; IList meshes = solidMeshCapsule.GetMeshes(); - ElementId overrideCatId = ElementId.InvalidElementId; + Category overrideCategory = null; bool initOverrideCatId = false; Document doc = element.Document; foreach (SolidInfo solidInfo in solidInfos) { - if (!ProcessObjectForGStyle(doc, solidInfo.Solid, ref overrideCatId, ref initOverrideCatId)) + if (!ProcessObjectForGStyle(doc, solidInfo.Solid, ref overrideCategory, ref initOverrideCatId)) return null; } foreach (Mesh mesh in meshes) { - if (!ProcessObjectForGStyle(doc, mesh, ref overrideCatId, ref initOverrideCatId)) + if (!ProcessObjectForGStyle(doc, mesh, ref overrideCategory, ref initOverrideCatId)) return null; } + return overrideCategory; + } + + private static string GetIFCClassNameOrTypeForMass(Element element, bool getClassName) + { + Category overrideCategory = GetCategoryForMass(element); if (getClassName) - return GetIFCClassNameFromExportTable(exporterIFC, overrideCatId); - else - { - // At the moment, we don't have the right API to get the type from a categoryId instead of from an element from the category table. As such, we are - // going to hardwire this. The only one that matters is OST_MassFloor. - if (overrideCatId == new ElementId(BuiltInCategory.OST_MassFloor)) - { - string className = GetIFCClassNameFromExportTable(exporterIFC, overrideCatId); - if (string.Compare(className, "IfcSlab", true) == 0) - return "FLOOR"; - if (string.Compare(className, "IfcCovering", true) == 0) - return "FLOORING"; - } + return GetIFCEntityNameFromExportTable(overrideCategory); - return null; // GetIFCTypeFromExportTable(exporterIFC, overrideCatId); + // At the moment, we don't have the right API to get the type from a categoryId instead of from an element + // from the category table. As such, we are going to hardwire this. The only one that matters is OST_MassFloor. + if ((overrideCategory?.Id.Value ?? -1) == (int) BuiltInCategory.OST_MassFloor) + { + string className = GetIFCEntityNameFromExportTable(overrideCategory); + if (string.Compare(className, "IfcSlab", true) == 0) + return "FLOOR"; + if (string.Compare(className, "IfcCovering", true) == 0) + return "FLOORING"; } + + return null; } - private static string GetIFCClassNameOrTypeForWalls(ExporterIFC exporterIFC, Wall wall, ElementId categoryId, bool getClassName) + private static ExportIFCCategoryInfo GetCategoryInfoForMass(Element element) + { + Category overrideCategory = GetCategoryForMass(element); + ElementId categoryId = overrideCategory?.Id ?? ElementId.InvalidElementId; + GetCategoryInfoById(categoryId, null, out ExportIFCCategoryInfo info); + return info; + } + + private static string GetIFCClassNameOrTypeForWalls(Wall wall, bool getClassName) { WallType wallType = wall.WallType; if (wallType == null) @@ -869,44 +986,46 @@ private static string GetIFCClassNameOrTypeForWalls(ExporterIFC exporterIFC, Wal if (ParameterUtil.GetIntValueFromElement(wallType, BuiltInParameter.FUNCTION_PARAM, out wallFunction) != null) { if (getClassName) - return GetIFCClassNameFromExportTable(exporterIFC, wall, categoryId, wallFunction); + return GetIFCEntityNameFromExportTable((WallFunction) wallFunction); else - return GetIFCTypeFromExportTable(exporterIFC, wall, categoryId, wallFunction); + return GetIFCTypeFromExportTable((WallFunction)wallFunction); } return null; } - private static bool ProcessObjectForGStyle(Document doc, GeometryObject geomObj, ref ElementId overrideCatId, ref bool initOverrideCatId) + private static ExportIFCCategoryInfo GetCategoryInfoForWalls(Wall wall) { - GraphicsStyle gStyle = doc.GetElement(geomObj.GraphicsStyleId) as GraphicsStyle; - if (gStyle == null) - return true; - - if (gStyle.GraphicsStyleCategory == null) - return true; + WallFunction? function = wall?.WallType?.Function; + GetCategoryInfoById(new ElementId(BuiltInCategory.OST_Walls), function, out ExportIFCCategoryInfo info); + return info; + } - ElementId currCatId = gStyle.GraphicsStyleCategory.Id; - if (currCatId == ElementId.InvalidElementId) + private static bool ProcessObjectForGStyle(Document doc, GeometryObject geomObj, + ref Category overrideCategory, ref bool initOverrideCatId) + { + GraphicsStyle gStyle = doc.GetElement(geomObj.GraphicsStyleId) as GraphicsStyle; + Category currCategory = gStyle?.GraphicsStyleCategory; + if (currCategory == null) return true; if (!initOverrideCatId) { initOverrideCatId = true; - overrideCatId = currCatId; + overrideCategory = currCategory; return true; } - if (currCatId != overrideCatId) + if (currCategory.Id != overrideCategory.Id) { - overrideCatId = ElementId.InvalidElementId; + overrideCategory = null; return false; } return true; } - private static string GetIFCClassNameOrTypeFromSpecialEntry(ExporterIFC exporterIFC, Element element, ElementId categoryId, bool getClassName) + private static string GetIFCClassNameOrTypeFromSpecialEntry(Element element, ElementId categoryId, bool getClassName) { if (element == null) return null; @@ -917,57 +1036,169 @@ private static string GetIFCClassNameOrTypeFromSpecialEntry(ExporterIFC exporter if (categoryId == new ElementId(BuiltInCategory.OST_Walls)) { if (element is Wall) - return GetIFCClassNameOrTypeForWalls(exporterIFC, element as Wall, categoryId, getClassName); + return GetIFCClassNameOrTypeForWalls(element as Wall, getClassName); } else if (categoryId == new ElementId(BuiltInCategory.OST_Mass)) { - return GetIFCClassNameOrTypeForMass(exporterIFC, element, categoryId, getClassName); + return GetIFCClassNameOrTypeForMass(element, getClassName); + } + + return null; + } + + private static ExportIFCCategoryInfo GetCategoryInfoForSpecialEntry(Element element, ElementId categoryId) + { + if (element == null) + return null; + + // We do special checks for Wall and Massing categories. + // For walls, we check if it is an interior or exterior wall. + // For massing, we check the geometry. If it is all in the same sub-category, we use that instead. + if (categoryId.Value == (int) BuiltInCategory.OST_Walls) + { + return GetCategoryInfoForWalls(element as Wall); + } + else if (categoryId.Value == (int) BuiltInCategory.OST_Mass) + { + return GetCategoryInfoForMass(element); } return null; } /// - /// Get the IFC class name assigned in the export layers table for a category. Cache values to avoid calls to internal code. + /// Get the category id that will be used for category mapping for this element. + /// + /// The element. + /// The category and element id of the category, if it exists. + public static (Category, ElementId) GetSpecificCategoryForElement(Element element) + { + Category actualCategory = CategoryUtil.GetSafeCategory(element); + + ElementId categoryId = actualCategory?.Id ?? ElementId.InvalidElementId; + if (categoryId == ElementId.InvalidElementId) + return (null, categoryId); + + // Special Case for Beams: if the structural usage is set, use that sub-category. + ElementId actualCategoryId = categoryId; + StructuralInstanceUsage usage = (element as FamilyInstance)?.StructuralUsage ?? StructuralInstanceUsage.Undefined; + switch (usage) + { + case StructuralInstanceUsage.Automatic: + case StructuralInstanceUsage.Column: + case StructuralInstanceUsage.Undefined: + case StructuralInstanceUsage.Wall: + break; + case StructuralInstanceUsage.Brace: + actualCategoryId = new ElementId(BuiltInCategory.OST_VerticalBracing); + break; + case StructuralInstanceUsage.Girder: + actualCategoryId = new ElementId(BuiltInCategory.OST_Girder); + break; + case StructuralInstanceUsage.HorizontalBracing: + actualCategoryId = new ElementId(BuiltInCategory.OST_HorizontalBracing); + break; + case StructuralInstanceUsage.Joist: + actualCategoryId = new ElementId(BuiltInCategory.OST_Joist); + break; + case StructuralInstanceUsage.KickerBracing: + actualCategoryId = new ElementId(BuiltInCategory.OST_KickerBracing); + break; + case StructuralInstanceUsage.Other: + { + if (categoryId == new ElementId(BuiltInCategory.OST_StructuralFraming)) + { + actualCategoryId = new ElementId(BuiltInCategory.OST_StructuralFramingOther); + } + break; + } + case StructuralInstanceUsage.Purlin: + actualCategoryId = new ElementId(BuiltInCategory.OST_Purlin); + break; + case StructuralInstanceUsage.TrussChord: + actualCategoryId = new ElementId(BuiltInCategory.OST_TrussChord); + break; + case StructuralInstanceUsage.TrussWeb: + actualCategoryId = new ElementId(BuiltInCategory.OST_TrussWeb); + break; + } + + if (actualCategoryId != categoryId) + { + actualCategory = Category.GetCategory(element.Document, actualCategoryId); + } + return (actualCategory, actualCategoryId); + } + + /// + /// Get the mapping information assigned in the IFC category table for a category. + /// + /// The element. + /// The returned category id. + /// The entity name. + public static ExportIFCCategoryInfo GetCategoryInfoFromExportTable(Element element, out ElementId categoryId) + { + Category category; + (category, categoryId) = GetSpecificCategoryForElement(element); + if (categoryId == ElementId.InvalidElementId) + return null; + + ExportIFCCategoryInfo info = GetCategoryInfoForSpecialEntry(element, categoryId); + if (!info?.IsDefault() ?? false) + { + return info; + } + + if (!GetCategoryInfoById(categoryId, null, out info)) + { + ElementId parentCategoryId = category.Parent?.Id ?? ElementId.InvalidElementId; + if (parentCategoryId != ElementId.InvalidElementId) + { + GetCategoryInfoById(parentCategoryId, null, out info); + } + } + + return info; + } + + /// + /// Get the IFC entity name assigned in the IFC category table for a category. /// - /// The exporterIFC class. /// The element. /// The returned category id. /// The entity name. - public static string GetIFCClassNameFromExportTable(ExporterIFC exporterIFC, - Element element, out ElementId categoryId) + public static string GetIFCEntityNameFromExportTable(Element element, out ElementId categoryId) { Category category = CategoryUtil.GetSafeCategory(element); categoryId = category?.Id ?? ElementId.InvalidElementId; - if (category == null) + if (categoryId == ElementId.InvalidElementId) return null; - string specialEntry = GetIFCClassNameOrTypeFromSpecialEntry(exporterIFC, element, categoryId, true); + string specialEntry = GetIFCClassNameOrTypeFromSpecialEntry(element, categoryId, true); if (specialEntry != null) return specialEntry; - return GetIFCClassNameFromExportTable(exporterIFC, categoryId); + return GetIFCEntityNameFromExportTable(category); } /// /// Get the IFC predefined type assigned in the export layers table for a category. Cache values to avoid calls to internal code. /// - /// The exporterIFC class. /// The element. /// The predefined type. - public static string GetIFCTypeFromExportTable(ExporterIFC exporterIFC, Element element) + public static string GetIFCTypeFromExportTable(Element element) { Category category = CategoryUtil.GetSafeCategory(element); if (category == null) return null; ElementId categoryId = category.Id; - string specialEntry = GetIFCClassNameOrTypeFromSpecialEntry(exporterIFC, element, categoryId, false); + string specialEntry = GetIFCClassNameOrTypeFromSpecialEntry(element, categoryId, false); if (specialEntry != null) return specialEntry; - return GetIFCTypeFromExportTable(exporterIFC, element, categoryId, -1); + return GetIFCTypeFromExportTable(category); } private class ApplicablePsets where T : Description @@ -1115,7 +1346,7 @@ public bool NeedSearch() else { if (!string.IsNullOrEmpty(currDesc.PredefinedType) - && currDesc.PredefinedType.Equals(exportInfo.ValidatedPredefinedType, StringComparison.InvariantCultureIgnoreCase) + && currDesc.PredefinedType.Equals(exportInfo.PredefinedType, StringComparison.InvariantCultureIgnoreCase) && currDesc.PredefinedType.Equals("USERDEFINED", StringComparison.InvariantCultureIgnoreCase)) userdefinedPdefType = true; } @@ -1145,7 +1376,7 @@ public bool NeedSearch() ByIfcEntityType.ByAltPredefinedType.Add(currDesc); } else if (!string.IsNullOrEmpty(currDesc.PredefinedType) && - currDesc.PredefinedType.Equals(exportInfo.ValidatedPredefinedType, StringComparison.InvariantCultureIgnoreCase)) + currDesc.PredefinedType.Equals(exportInfo.PredefinedType, StringComparison.InvariantCultureIgnoreCase)) { if (addToInstance) ByIfcEntity.ByPredefinedType.Add(currDesc); @@ -1244,7 +1475,7 @@ public static IFCExportInfoPair GetExportInfoForProperties(IFCAnyHandle prodHnd) { IFCEntityType altProdHndType = IFCEntityType.UnKnown; if (Enum.TryParse("IfcFurnitureType", true, out altProdHndType)) - exportInfo.SetValue(prodHndType, altProdHndType, exportInfo.ValidatedPredefinedType); + exportInfo.SetValue(prodHndType, altProdHndType, exportInfo.PredefinedType); } } else if (IFCAnyHandleUtil.IsSubTypeOf(prodHnd, IFCEntityType.IfcTypeObject)) @@ -1253,11 +1484,11 @@ public static IFCExportInfoPair GetExportInfoForProperties(IFCAnyHandle prodHnd) ElementTypeKey etKey = ExporterCacheManager.ElementTypeToHandleCache.Find(prodHnd); if (etKey != null) { - exportInfo.SetValueWithPair(etKey.Item2, etKey.Item3); + exportInfo.SetByTypeAndPredefinedType(etKey.Item2, etKey.Item3); } else { - exportInfo.SetValueWithPair(prodHndType); + exportInfo.SetByType(prodHndType); } // Need to handle backward compatibility for IFC2x3 @@ -1266,7 +1497,7 @@ public static IFCExportInfoPair GetExportInfoForProperties(IFCAnyHandle prodHnd) { IFCEntityType altProdHndType = IFCEntityType.UnKnown; if (Enum.TryParse("IfcFurnishingElement", true, out altProdHndType)) - exportInfo.SetValue(prodHndType, altProdHndType, exportInfo.ValidatedPredefinedType); + exportInfo.SetValue(prodHndType, altProdHndType, exportInfo.PredefinedType); } } else @@ -1337,12 +1568,12 @@ public static IFCExportInfoPair GetExportInfoForProperties(IFCAnyHandle prodHnd) applicablePsets.ByIfcEntityType.ByType = GetCachedValue(processType, cacheToUse, typeEntity, null); - if (!string.IsNullOrEmpty(exportInfo.ValidatedPredefinedType)) + if (!exportInfo.IsPredefinedTypeDefault) { applicablePsets.ByIfcEntity.ByPredefinedType = - GetCachedValue(processInstance, cacheToUse, instanceEntity, exportInfo.ValidatedPredefinedType); + GetCachedValue(processInstance, cacheToUse, instanceEntity, exportInfo.PredefinedType); applicablePsets.ByIfcEntityType.ByPredefinedType = - GetCachedValue(processType, cacheToUse, typeEntity, exportInfo.ValidatedPredefinedType); + GetCachedValue(processType, cacheToUse, typeEntity, exportInfo.PredefinedType); } if (!string.IsNullOrEmpty(objectType)) @@ -1404,11 +1635,8 @@ public static IFCExportInfoPair GetExportInfoForProperties(IFCAnyHandle prodHnd) IFCEntityType typeEntity = (processType && unknownType) ? exportInfo.ExportInstance : exportInfo.ExportType; - currPsets.PopulateCache(exportInfo.ExportInstance, - typeEntity, - exportInfo.ValidatedPredefinedType, - objectType, - cacheToUse); + currPsets.PopulateCache(exportInfo.ExportInstance, typeEntity, exportInfo.PredefinedType, + objectType, cacheToUse); } currPsets.PopulateFromCache(cachedPsets); @@ -1695,6 +1923,16 @@ private static void ExportElementQuantities(ExporterIFC exporterIFC, Element ele } } + if (ExporterCacheManager.BaseQuantitiesCache.TryGetValue(prodHnd, out addQuantity)) + { + foreach (IFCAnyHandle addQty in addQuantity) + { + quantities.Add(addQty); + string addQtyName = IFCAnyHandleUtil.GetStringAttribute(addQty, "Name"); + uniqueQuantityNames.Add(addQtyName); + } + } + IFCExportBodyParams ifcParams = productWrapper.FindExtrusionCreationParameters(prodHnd); HashSet qtyFromInit = currDesc.ProcessEntries(file, exporterIFC, ifcParams, elementToUse, elemTypeToUse); @@ -1782,8 +2020,13 @@ private static void ExportElementClassifications(ExporterIFC exporterIFC, Elemen if (productSet.Count > 1 && prodHnd == productSet.First() && IFCAnyHandleUtil.IsTypeOf(prodHnd, IFCEntityType.IfcElementAssembly)) continue; //Classification for the ELementAssembly should have been created before when processing ElementAssembly + ElementId elementId = ExporterCacheManager.HandleToElementCache.Find(prodHnd); + Element elementToUse = (elementId == ElementId.InvalidElementId) ? element : element?.Document?.GetElement(elementId); + if (elementToUse == null) + continue; + // No need to check the subtype since Classification can be assigned to IfcRoot - ClassificationUtil.CreateClassification(exporterIFC, file, element, prodHnd); + ClassificationUtil.CreateClassification(exporterIFC, file, elementToUse, prodHnd); } transaction.Commit(); } @@ -1880,7 +2123,7 @@ public static string GetExportTypeFromTypeParameter(Element element, Element ele if (!string.IsNullOrEmpty(predefType)) { - exportType.ValidatedPredefinedType = predefType; + exportType.PredefinedType = predefType; } return exportType; @@ -1912,6 +2155,23 @@ private static IFCExportInfoPair GetExportTypeForFurniture(ExporterIFC exporterI return IFCExportInfoPair.UnKnown; } + private static IFCExportInfoPair GetExportTypeForCurtainSystem(Element element, string predefinedType) + { + if (CurtainSystemExporter.IsCurtainSystem(element) || CurtainSystemExporter.IsLegacyCurtainElement(element)) + { + if (element is RoofBase) + { + return new IFCExportInfoPair(IFCEntityType.IfcRoof, predefinedType); + } + else + { + return new IFCExportInfoPair(IFCEntityType.IfcCurtainWall, predefinedType); + } + } + + return IFCExportInfoPair.UnKnown; + } + private static IFCExportInfoPair OverrideExportTypeForStructuralFamilies(Element element, IFCExportInfoPair originalExportInfoPair) { @@ -1924,7 +2184,7 @@ private static IFCExportInfoPair GetExportTypeForFurniture(ExporterIFC exporterI if (familyInstance == null) return originalExportInfoPair; - string enumTypeValue = originalExportInfoPair.ValidatedPredefinedType; + string enumTypeValue = originalExportInfoPair.PredefinedType; switch (familyInstance.StructuralType) { @@ -1968,11 +2228,12 @@ private static IFCExportInfoPair GetExportTypeForFurniture(ExporterIFC exporterI // in the IFC Export Options table. If so, this overrides all other settings. // 2. For the special case of an element in a group, check if it in an IfcFurniture group. // 3. Check the parameters IFC_EXPORT_ELEMENT*_AS. - // 4. Look at class specified by the IFC Export Options table in step 1, if set. - // 5. Check at a pre-defined mapping from Revit category to IFC entity and pre-defined type. - // 6. Check whether the intended Entity type is inside the export exclusion set. - // 7. Check whether we override IfcBuildingElementProxy/Unknown values with structural known values. - // 8. Check to see if we should override the ValidatedPredefinedType from IFC_EXPORT_PREDEFINEDTYPE*. + // 4. If Element is intended to be exported as a curtain systen, find the default export settings for that. + // 5. Look at class specified by the IFC Export Options table in step 1, if set. + // 6. Check at a pre-defined mapping from Revit category to IFC entity and pre-defined type. + // 7. Check whether the intended Entity type is inside the export exclusion set. + // 8. Check whether we override IfcBuildingElementProxy/Unknown values with structural known values. + // 9. Check to see if we should override the ValidatedPredefinedType from IFC_EXPORT_PREDEFINEDTYPE*. // Steps start below. @@ -1983,10 +2244,12 @@ private static IFCExportInfoPair GetExportTypeForFurniture(ExporterIFC exporterI // Note that this means that if the Walls category is not exported, but a wall is set to be // exported as, e.g., an IfcCeilingType, it won't be exported. We may want to reconsider this // in the future based on customer feedback. - ElementId categoryId; - string ifcClassName = GetIFCClassNameFromExportTable(exporterIFC, element, out categoryId); - if (categoryId == ElementId.InvalidElementId) + ElementId categoryId = ElementId.InvalidElementId; + string ifcClassName = null; + ExportIFCCategoryInfo info = GetCategoryInfoFromExportTable(element, out categoryId); + if (info != null && !info.IFCExportFlag) return IFCExportInfoPair.UnKnown; + ifcClassName = info?.IFCEntityName; // 2. If Element is contained within a Group that is exported as IfcFurniture, it should be // exported as an IfcSystemFurnitureElement, regardless of other settings. @@ -2000,48 +2263,58 @@ private static IFCExportInfoPair GetExportTypeForFurniture(ExporterIFC exporterI isExportTypeDefinedInParameters = !exportType.IsUnKnown; } - // 4. Look at class specified by the IFC Export Options table in step 1. + // 4. If Element is intended to be exported as a curtain systen, find the default export + // settings for that. + if (!isExportTypeDefinedInParameters) + { + exportType = GetExportTypeForCurtainSystem(element, exportType.PredefinedType); + } + + // 5. Look at class specified by the IFC Export Options table in step 1. if (exportType.IsUnKnown && !string.IsNullOrEmpty(ifcClassName)) { if (string.IsNullOrEmpty(enumTypeValue)) - enumTypeValue = GetIFCTypeFromExportTable(exporterIFC, element); + { + enumTypeValue = info?.IFCPredefinedType ?? GetIFCTypeFromExportTable(element); + } + // if using name, override category id if match is found. if (!ifcClassName.Equals("Default", StringComparison.OrdinalIgnoreCase)) { exportType = ElementFilteringUtil.GetExportTypeFromClassName(ifcClassName); - exportType.ValidatedPredefinedType = enumTypeValue; + exportType.PredefinedType = enumTypeValue; } } - // 5. Check at a pre-defined mapping from Revit category to IFC entity and pre-defined type. + // 6. Check at a pre-defined mapping from Revit category to IFC entity and pre-defined type. if (exportType.IsUnKnown) { exportType = ElementFilteringUtil.GetExportTypeFromCategoryId(categoryId); if (string.IsNullOrEmpty(enumTypeValue)) - enumTypeValue = exportType.ValidatedPredefinedType; + enumTypeValue = exportType.PredefinedType; } - // 6. Check whether the intended Entity type is inside the export exclusion set. If it is, + // 7. Check whether the intended Entity type is inside the export exclusion set. If it is, // we are done - we won't export it. if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(exportType.ExportInstance)) return IFCExportInfoPair.UnKnown; - // 7. Check whether we override IfcBuildingElementProxy/Unknown values with + // 8. Check whether we override IfcBuildingElementProxy/Unknown values with // structural known values. if (!isExportTypeDefinedInParameters) exportType = OverrideExportTypeForStructuralFamilies(element, exportType); - // 8. Check to see if we should override the ValidatedPredefinedType from + // 9. Check to see if we should override the ValidatedPredefinedType from // IFC_EXPORT_PREDEFINEDTYPE*. string pdefFromParam = GetExportTypeFromTypeParameter(element, null); if (!string.IsNullOrEmpty(pdefFromParam)) enumTypeValue = pdefFromParam; if (!string.IsNullOrEmpty(enumTypeValue)) - exportType.ValidatedPredefinedType = enumTypeValue; + exportType.PredefinedType = enumTypeValue; // Set the out parameter here. - enumTypeValue = exportType.ValidatedPredefinedType; + enumTypeValue = exportType.PredefinedType; if (string.IsNullOrEmpty(enumTypeValue)) enumTypeValue = "NOTDEFINED"; @@ -2858,15 +3131,23 @@ public static ExportPartAs ShouldExportByComponentsOrParts(Element element, int /// /// the element /// whether it can be exported by components or parts - public static ExportPartAs CanExportByComponentsOrParts(Element element) + public static ExportPartAs CanExportByComponentsOrParts(Element element, ref GeometryElement geomElem) { ExportPartAs exportPartAs = ShouldExportByComponentsOrParts(element, PartUtils.GetAssociatedParts(element.Document, element.Id, false, true).Count); - if (PartUtils.HasAssociatedParts(element.Document, element.Id) && (exportPartAs == ExportPartAs.Part || exportPartAs == ExportPartAs.ShapeAspect)) + if (!PartUtils.HasAssociatedParts(element.Document, element.Id)) { - return exportPartAs; + exportPartAs = ExportPartAs.None; } - return ExportPartAs.None; + // We may have previously nuked the geometry because we thought we were going to export parts. However, for + // some reason or other we decided not to, so we need to get the geometry again. An open question is why we + // thought we were exporting parts when we weren't. + if (exportPartAs == ExportPartAs.None && geomElem == null) + { + geomElem = element.get_Geometry(GeometryUtil.GetIFCExportGeometryOptions()); + } + + return exportPartAs; } /// @@ -2877,30 +3158,35 @@ public static ExportPartAs CanExportByComponentsOrParts(Element element) /// true - if parts have been successfully created. false - is creation of parts is not possible. public static bool CreateParts(Element element, int layersCount, ref GeometryElement geometryElement) { + if (!ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView) + return false; + ExportPartAs exportPartAs = ShouldExportByComponentsOrParts(element, layersCount); + if (exportPartAs != ExportPartAs.Part && exportPartAs != ExportPartAs.ShapeAspect) + return false; + + Document doc = element.Document; + ICollection ids = new List() { element.Id }; + if (!PartUtils.AreElementsValidForCreateParts(doc, ids)) + return false; + + PartUtils.CreateParts(doc, ids); + doc.Regenerate(); - if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView && (exportPartAs == ExportPartAs.Part || exportPartAs == ExportPartAs.ShapeAspect)) + //geometryElement is either re-acquired or set to null here because call to PartUtils.CreateParts() and doc.Regenerate() can invalidate its value. + if (exportPartAs == ExportPartAs.ShapeAspect) { - Document doc = element.Document; - ICollection ids = new List() { element.Id }; - if (PartUtils.AreElementsValidForCreateParts(doc, ids)) - { - PartUtils.CreateParts(doc, ids); - doc.Regenerate(); - - //geometryElement is either re-acquired or set to null here because call to PartUtils.CreateParts() and doc.Regenerate() can invalidate its value. - if (exportPartAs == ExportPartAs.ShapeAspect) - //If we export Shape Aspects we will also export original geometry because Shape Aspects reference it. - //When exporting original geometry the code will use GeometryElement so get it now. - geometryElement = element.get_Geometry(GeometryUtil.GetIFCExportGeometryOptions()); - else - //If we export Parts we do not need to export original geometry so set geometryElement to null. - geometryElement = null; - return true; - } + //If we export Shape Aspects we will also export original geometry because Shape Aspects reference it. + //When exporting original geometry the code will use GeometryElement so get it now. + geometryElement = element.get_Geometry(GeometryUtil.GetIFCExportGeometryOptions()); + } + else + { + //If we export Parts we do not need to export original geometry so set geometryElement to null. + geometryElement = null; } - return false; + return true; } /// @@ -2923,6 +3209,11 @@ public static bool ExportingHostModel() (ExporterCacheManager.BaseLinkedDocumentGUID == null); } - + /// + /// Detects if Element is part of Assembly. This is useful during Export. + /// + /// Element to check. + /// True if non-null Element is part of Assembly, false otherwise. + public static bool IsContainedInAssembly(Element element) => ((element?.AssemblyInstanceId ?? ElementId.InvalidElementId) != ElementId.InvalidElementId); } } \ No newline at end of file diff --git a/Source/Revit.IFC.Export/Utility/FamilyExporterUtil.cs b/Source/Revit.IFC.Export/Utility/FamilyExporterUtil.cs index 3626e217..48b9be10 100644 --- a/Source/Revit.IFC.Export/Utility/FamilyExporterUtil.cs +++ b/Source/Revit.IFC.Export/Utility/FamilyExporterUtil.cs @@ -237,8 +237,7 @@ public static bool IsFurnitureSubType(IFCExportInfoPair exportType) IFCAnyHandle localPlacementToUse = useOverridePlacement ? overrideLocalPlacement : setter.LocalPlacement; - bool isChildInContainer = - (familyInstance.AssemblyInstanceId != ElementId.InvalidElementId) || useOverridePlacement; + bool isChildInContainer = ExporterUtil.IsContainedInAssembly(familyInstance) || useOverridePlacement; ElementId roomId = ElementId.InvalidElementId; if (IsRoomRelated(type)) @@ -265,8 +264,7 @@ public static bool IsFurnitureSubType(IFCExportInfoPair exportType) break; } - string preDefinedType = string.IsNullOrWhiteSpace(type.ValidatedPredefinedType) ? - defaultPreDefinedType : type.ValidatedPredefinedType; + string preDefinedType = type.IsPredefinedTypeDefault ? defaultPreDefinedType : type.PredefinedType; IFCAnyHandle instanceHandle = null; switch (type.ExportInstance) @@ -333,7 +331,9 @@ public static bool IsFurnitureSubType(IFCExportInfoPair exportType) } case IFCEntityType.IfcSpace: { - IFCInternalOrExternal internalOrExternal = CategoryUtil.IsElementExternal(familyInstance) ? IFCInternalOrExternal.External : IFCInternalOrExternal.Internal; + IFCInternalOrExternal internalOrExternal = IFCInternalOrExternal.NotDefined; + if(CategoryUtil.IsElementExternal(familyInstance).HasValue) + internalOrExternal = CategoryUtil.IsElementExternal(familyInstance).Value? IFCInternalOrExternal.External : IFCInternalOrExternal.Internal; instanceHandle = IFCInstanceExporter.CreateSpace(exporterIFC, familyInstance, instanceGUID, ownerHistory, localPlacementToUse, productRepresentation, @@ -415,7 +415,6 @@ public static bool IsFurnitureSubType(IFCExportInfoPair exportType) /// If the guid is not provided, it will be generated from the elementType. public static IFCAnyHandle ExportGenericType(ExporterIFC exporterIFC, IFCExportInfoPair type, - string ifcEnumType, HashSet propertySets, IList representationMapList, Element instance, @@ -450,7 +449,7 @@ public static bool IsFurnitureSubType(IFCExportInfoPair exportType) // TODO_GUID: This is just a patch at the moment. We should fix the callers of // this function so that we don't need to do this here. Furthermore, we should // take into account the exportType into the guid generation. - type = AdjustExportTypeForSchema(type, type.ValidatedPredefinedType); + type = AdjustExportTypeForSchema(type); typeHandle = IFCInstanceExporter.CreateGenericIFCType(type, elementType, guid, file, propertySets, representationMapList); @@ -465,23 +464,23 @@ public static bool IsFurnitureSubType(IFCExportInfoPair exportType) return typeHandle; } - public static IFCExportInfoPair AdjustExportTypeForSchema(IFCExportInfoPair exportType, - string ifcEnumType) + public static IFCExportInfoPair AdjustExportTypeForSchema(IFCExportInfoPair exportType) { IFCExportInfoPair exportInfo = exportType; + string ifcEnumType = exportType.PredefinedType; if (ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4) { // Handle special cases for upward compatibility switch (exportType.ExportType) { case IFCEntityType.IfcBurnerType: - exportInfo.SetValueWithPair(IFCEntityType.IfcGasTerminalType, ifcEnumType); + exportInfo.SetByTypeAndPredefinedType(IFCEntityType.IfcGasTerminalType, ifcEnumType); break; case IFCEntityType.IfcDoorType: - exportInfo.SetValueWithPair(IFCEntityType.IfcDoorStyle, ifcEnumType); + exportInfo.SetByTypeAndPredefinedType(IFCEntityType.IfcDoorStyle, ifcEnumType); break; case IFCEntityType.IfcWindowType: - exportInfo.SetValueWithPair(IFCEntityType.IfcWindowStyle, ifcEnumType); + exportInfo.SetByTypeAndPredefinedType(IFCEntityType.IfcWindowStyle, ifcEnumType); break; case IFCEntityType.UnKnown: { @@ -500,17 +499,17 @@ public static bool IsFurnitureSubType(IFCExportInfoPair exportType) { // For compatibility with IFC2x3 and before. IfcGasTerminalType has been removed and IfcBurnerType replaces it in IFC4 case IFCEntityType.IfcGasTerminalType: - exportInfo.SetValueWithPair(IFCEntityType.IfcBurnerType, ifcEnumType); + exportInfo.SetByTypeAndPredefinedType(IFCEntityType.IfcBurnerType, ifcEnumType); break; // For compatibility with IFC2x3 and before. IfcElectricHeaterType has been removed and IfcSpaceHeaterType replaces it in IFC4 case IFCEntityType.IfcElectricHeaterType: - exportInfo.SetValueWithPair(IFCEntityType.IfcSpaceHeaterType, ifcEnumType); + exportInfo.SetByTypeAndPredefinedType(IFCEntityType.IfcSpaceHeaterType, ifcEnumType); break; case IFCEntityType.UnKnown: { if (exportType.ExportInstance == IFCEntityType.IfcFooting) { - exportInfo.SetValueWithPair(IFCEntityType.IfcFootingType, ifcEnumType); + exportInfo.SetByTypeAndPredefinedType(IFCEntityType.IfcFootingType, ifcEnumType); } break; } @@ -596,37 +595,21 @@ private static bool IsRoomRelated(IFCExportInfoPair exportType) Category graphicsStyleCategory = gStyle.GraphicsStyleCategory; if (graphicsStyleCategory != null) { - // Remove the geometry that is not visible - if (!ElementFilteringUtil.IsCategoryVisible(graphicsStyleCategory, filterView)) + bool removeObject = !ElementFilteringUtil.ShouldCategoryBeExported(graphicsStyleCategory, false); + + if (removeObject) { if (obj is Solid) + { solids.Remove(obj as Solid); + } else if (obj is Mesh) + { meshes.Remove(obj as Mesh); + } continue; } - - ElementId catId = graphicsStyleCategory.Id; - - string ifcClassName = ExporterUtil.GetIFCClassNameFromExportTable(exporterIFC, catId); - if (!string.IsNullOrEmpty(ifcClassName)) - { - bool foundName = String.Compare(ifcClassName, "Default", true) != 0; - if (foundName) - { - IFCExportInfoPair exportType = ElementFilteringUtil.GetExportTypeFromClassName(ifcClassName); - if (exportType.ExportInstance == IFCEntityType.UnKnown) - { - if (obj is Solid) - solids.Remove(obj as Solid); - else if (obj is Mesh) - meshes.Remove(obj as Mesh); - - continue; - } - } - } } } geomObjectsOut.Add(obj); diff --git a/Source/Revit.IFC.Export/Utility/FootPrintInfo.cs b/Source/Revit.IFC.Export/Utility/FootPrintInfo.cs index c52635f4..3098da74 100644 --- a/Source/Revit.IFC.Export/Utility/FootPrintInfo.cs +++ b/Source/Revit.IFC.Export/Utility/FootPrintInfo.cs @@ -119,10 +119,8 @@ public IFCAnyHandle CreateFootprintShapeRepresentation(ExporterIFC exporterIFC) ISet repItems = new HashSet(); foreach (CurveLoop extrusionBoundaryLoop in ExtrusionBaseLoops) { - IFCAnyHandle footprintGeomRepItem = GeometryUtil.CreateIFCCurveFromCurveLoop(exporterIFC, extrusionBoundaryLoop, - ExtrusionBaseLCS, new XYZ(0, 0, 1.0)); - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(footprintGeomRepItem)) - repItems.Add(footprintGeomRepItem); + repItems.AddIfNotNull(GeometryUtil.CreateIFCCurveFromCurveLoop(exporterIFC, + extrusionBoundaryLoop, ExtrusionBaseLCS, XYZ.BasisZ)); } IFCAnyHandle footprintShapeRep = null; diff --git a/Source/Revit.IFC.Export/Utility/GUIDUtil.cs b/Source/Revit.IFC.Export/Utility/GUIDUtil.cs index 8ab615df..f1b49665 100644 --- a/Source/Revit.IFC.Export/Utility/GUIDUtil.cs +++ b/Source/Revit.IFC.Export/Utility/GUIDUtil.cs @@ -294,7 +294,7 @@ public static GUIDString CreateGUIDString(IFCEntityType type, string uniqueKey) { IFCEntityType entityType = useInstanceGeometry ? exportInfoPair.ExportInstance : exportInfoPair.ExportType; - string predefinedType = exportInfoPair.ValidatedPredefinedType ?? string.Empty; + string predefinedType = exportInfoPair.PredefinedType ?? string.Empty; hash += " Entity: " + entityType.ToString() + ":" + predefinedType; } diff --git a/Source/Revit.IFC.Export/Utility/GeometryUtil.cs b/Source/Revit.IFC.Export/Utility/GeometryUtil.cs index 4d1c7044..7450fd51 100644 --- a/Source/Revit.IFC.Export/Utility/GeometryUtil.cs +++ b/Source/Revit.IFC.Export/Utility/GeometryUtil.cs @@ -34,6 +34,16 @@ namespace Revit.IFC.Export.Utility /// public class GeometryUtil { + /// + /// An enum used in CreateIFCCurveFromRevitCurve to determine how to create + /// the Revit curve in IFC entities. + /// + public enum TrimCurvePreference + { + BaseCurve, // Do not trim the curve. + TrimmedCurve, // Use a base curve and trim the curve + UsePolyLineOrTrim, // Use a polyline for a bounded line, otherwise trim. + } /// /// The comparer for comparing XYZ. /// @@ -663,7 +673,7 @@ public static SolidMeshGeometryInfo GetSolidMeshGeometry(GeometryElement geomEle if (geomElemToUse != null) { // call to recursive helper method to obtain all solid and mesh geometry within geomElemToUse - CollectSolidMeshGeometry(geomElemToUse, null, trf, geometryInfo); + geometryInfo.CollectSolidMeshGeometry(geomElemToUse, ExporterCacheManager.AllocatedGeometryObjectCache); } return geometryInfo; } @@ -716,7 +726,7 @@ public static SolidMeshGeometryInfo GetClippedSolidMeshGeometry(GeometryElement public static SolidMeshGeometryInfo GetSplitSolidMeshGeometry(GeometryElement geomElemToUse, Transform trf) { SolidMeshGeometryInfo geometryInfo = GetSolidMeshGeometry(geomElemToUse, Transform.Identity); - geometryInfo.SplitSolidsList(); + SplitSolids(geometryInfo); return geometryInfo; } @@ -752,99 +762,81 @@ public static SolidMeshGeometryInfo GetSplitClippedSolidMeshGeometry(GeometryEle return GetSplitSolidMeshGeometry(geomElemToUse); SolidMeshGeometryInfo geometryInfo = GetClippedSolidMeshGeometry(geomElemToUse, range); - geometryInfo.SplitSolidsList(); + SplitSolids(geometryInfo); return geometryInfo; } /// - /// Transforms a geometry by a given transform. + /// The maximum number of faces in a Solid before we decide not to split it. + /// Larger than this can cause sigificant performance issues. /// - /// The geometry element created by "GetTransformed" is a copy which will have its own allocated - /// membership - this needs to be stored and disposed of (see AllocatedGeometryObjectCache - /// for details) - /// The geometry. - /// The transform. - /// The transformed geometry. - public static GeometryElement GetTransformedGeometry(GeometryElement geomElem, Transform trf) - { - if (geomElem == null) - return null; - - GeometryElement currGeomElem = geomElem.GetTransformed(trf); - ExporterCacheManager.AllocatedGeometryObjectCache.AddGeometryObject(currGeomElem); - return currGeomElem; - } + /// + /// Internal tests show perfectly good behavior at 1044 faces, so setting + /// this value based on that. This may be tweaked over time, or other + /// methods used instead. + /// + public static int MaxFaceCountForSplitVolumes = 2048; /// - /// Collects all solids and meshes within all nested levels of a given GeometryElement. + /// Splits a Solid into distinct volumes. /// - /// - /// This is a private helper method for the GetSolidMeshGeometry type collection methods. - /// - /// The GeometryElement we are collecting solids and meshes from. - /// The element that contains the geomElem. It can be null. - /// The initial Transform applied on the GeometryElement. - /// The SolidMeshGeometryInfo object that contains the lists of collected solids and meshes. - private static void CollectSolidMeshGeometry(GeometryElement geomElem, - Element containingElement, Transform trf, SolidMeshGeometryInfo solidMeshCapsule) + /// The initial solid. + /// The list of volumes. + /// This calls the internal SolidUtils.SplitVolumes routine, but does additional cleanup work to properly dispose of stale data. + public static IList SplitVolumes(Solid solid) { - if (geomElem == null) - return; - - GeometryElement currGeomElem = geomElem; - Transform localTrf = trf; - if (localTrf == null) - localTrf = Transform.Identity; - else if (!localTrf.IsIdentity) - currGeomElem = GetTransformedGeometry(geomElem, localTrf); - - // iterate through the GeometryObjects contained in the GeometryElement - foreach (GeometryObject geomObj in currGeomElem) + IList splitVolumes = null; + try { - // Add try catch here because in a rare cases we find solid that throws exception/invalid solid.Faces - try + if (solid.Faces.Size < GeometryUtil.MaxFaceCountForSplitVolumes) { - Solid solid = geomObj as Solid; - if (solid != null && solid.Faces.Size > 0) - { - solidMeshCapsule.AddSolid(solid, containingElement); - } - else - { - Mesh mesh = geomObj as Mesh; - if (mesh != null) - { - solidMeshCapsule.AddMesh(mesh); - } - else - { - // if the current geomObj is castable as a GeometryInstance, then we perform the same collection on its symbol geometry - GeometryInstance inst = geomObj as GeometryInstance; + splitVolumes = SolidUtils.SplitVolumes(solid); - if (inst != null) - { - try - { - GeometryElement instanceSymbol = inst.GetSymbolGeometry(); - if (instanceSymbol != null && instanceSymbol.Count() != 0) - { - Transform instanceTransform = localTrf.Multiply(inst.Transform); - Element symbol = inst.GetDocument()?.GetElement(inst.GetSymbolGeometryId().SymbolId); - CollectSolidMeshGeometry(instanceSymbol, symbol, - instanceTransform, solidMeshCapsule); - } - } - catch - { - } - } - } + // Fall back to exporting just the original Solid if we got any Solids without volume + if (splitVolumes.Any(x => x.Volume < 0.0 || MathUtil.IsAlmostEqual(x.Volume, 0.0))) + throw new InvalidOperationException(); + + foreach (Solid currSolid in splitVolumes) + { + // The geometry element created by SplitVolumes is a copy which will have its own allocated + // membership - this needs to be stored and disposed of (see AllocatedGeometryObjectCache + // for details) + ExporterCacheManager.AllocatedGeometryObjectCache.AddGeometryObject(currSolid); } } - catch + } + catch + { + splitVolumes = null; + } + + if (splitVolumes == null) + { + // Split volumes can fail; in this case, we'll export the original solid. + splitVolumes = new List() { solid }; + } + + return splitVolumes; + } + + /// + /// Splits any solid volumes which consist of multiple closed bodies into individual solids (and updates the storage accordingly). + /// + public static void SplitSolids(SolidMeshGeometryInfo info) + { + IList splitSolidsList = new List(); + + foreach (SolidInfo solidInfo in info.SolidInfoList) + { + Element element = solidInfo.OwnerElement; + IList splitSolids = GeometryUtil.SplitVolumes(solidInfo.Solid); + foreach (Solid splitSolid in splitSolids) { + splitSolidsList.Add(new SolidInfo(splitSolid, element)); } } + + info.SolidInfoList = splitSolidsList; } /// @@ -1222,8 +1214,6 @@ private static CurveLoop GetOuterFaceBoundary(Face face, XYZ baseLoopOffset, boo int numBoundaries = faceEdges.Size; if (numBoundaries == 0) continue; - if (numBoundaries > 1) - throw new Exception("Can't handle faces with interior boundaries."); // In some cases the native function throws an exception, skip this face if it occurs ICollection generatingElementIds; @@ -2238,6 +2228,12 @@ private static IFCAnyHandle CreateBoundsIfNecessary(IFCFile file, IFCAnyHandle c /// The arc handle. public static IFCAnyHandle CreateArcSegment(ExporterIFC exporterIFC, Arc arc) { + double arcRadius = UnitUtil.ScaleLength(arc.Radius); + if (!IFCInstanceExporter.ValidateCircle(arcRadius)) + { + return null; + } + IFCFile file = exporterIFC.GetFile(); XYZ centerPoint = ExporterIFCUtils.TransformAndScalePoint(exporterIFC, arc.Center); @@ -2247,8 +2243,6 @@ public static IFCAnyHandle CreateArcSegment(ExporterIFC exporterIFC, Arc arc) XYZ xDirection = ExporterIFCUtils.TransformAndScaleVector(exporterIFC, arc.XDirection); IFCAnyHandle axis = ExporterUtil.CreateAxis2Placement3D(file, centerPoint, arc.Normal, xDirection); - double arcRadius = UnitUtil.ScaleLength(arc.Radius); - IFCAnyHandle circle = IFCInstanceExporter.CreateCircle(file, axis, arcRadius); return CreateBoundsIfNecessary(file, circle, arc); } @@ -2261,6 +2255,13 @@ public static IFCAnyHandle CreateArcSegment(ExporterIFC exporterIFC, Arc arc) /// The ellipse handle. public static IFCAnyHandle CreateEllipticalArcSegment(ExporterIFC exporterIFC, Ellipse ellipticalArc) { + double ellipseRadiusX = UnitUtil.ScaleLength(ellipticalArc.RadiusX); + double ellipseRadiusY = UnitUtil.ScaleLength(ellipticalArc.RadiusY); + if (!IFCInstanceExporter.ValidateEllipse(ellipseRadiusX, ellipseRadiusY)) + { + return null; + } + IFCFile file = exporterIFC.GetFile(); XYZ centerPoint = ExporterIFCUtils.TransformAndScalePoint(exporterIFC, ellipticalArc.Center); @@ -2270,9 +2271,6 @@ public static IFCAnyHandle CreateEllipticalArcSegment(ExporterIFC exporterIFC, E XYZ xDirection = ExporterIFCUtils.TransformAndScaleVector(exporterIFC, ellipticalArc.XDirection); IFCAnyHandle axis = ExporterUtil.CreateAxis2Placement3D(file, centerPoint, ellipticalArc.Normal, xDirection); - double ellipseRadiusX = UnitUtil.ScaleLength(ellipticalArc.RadiusX); - double ellipseRadiusY = UnitUtil.ScaleLength(ellipticalArc.RadiusY); - IFCAnyHandle ellipse = IFCInstanceExporter.CreateEllipse(file, axis, ellipseRadiusX, ellipseRadiusY); return CreateBoundsIfNecessary(file, ellipse, ellipticalArc); } @@ -2712,17 +2710,6 @@ public static double ComputePolygonalLoopArea(IList loop, XYZ normal, XYZ r return area / 2.0; } - /// - /// The maximum number of faces in a Solid before we decide not to split it. - /// Larger than this can cause sigificant performance issues. - /// - /// - /// Internal tests show perfectly good behavior at 1044 faces, so setting - /// this value based on that. This may be tweaked over time, or other - /// methods used instead. - /// - public static int MaxFaceCountForSplitVolumes = 2048; - /// /// Gets the volume of a solid, if it is possible. /// @@ -2740,49 +2727,6 @@ public static double ComputePolygonalLoopArea(IList loop, XYZ normal, XYZ r } } - /// - /// Splits a Solid into distinct volumes. - /// - /// The initial solid. - /// The list of volumes. - /// This calls the internal SolidUtils.SplitVolumes routine, but does additional cleanup work to properly dispose of stale data. - public static IList SplitVolumes(Solid solid) - { - IList splitVolumes = null; - try - { - if (solid.Faces.Size < GeometryUtil.MaxFaceCountForSplitVolumes) - { - splitVolumes = SolidUtils.SplitVolumes(solid); - - // Fall back to exporting just the original Solid if we got any Solids without volume - if (splitVolumes.Any(x => x.Volume < 0.0 || MathUtil.IsAlmostEqual(x.Volume, 0.0))) - throw new InvalidOperationException(); - - foreach (Solid currSolid in splitVolumes) - { - // The geometry element created by SplitVolumes is a copy which will have its own allocated - // membership - this needs to be stored and disposed of (see AllocatedGeometryObjectCache - // for details) - ExporterCacheManager.AllocatedGeometryObjectCache.AddGeometryObject(currSolid); - } - } - } - catch - { - splitVolumes = null; - } - - if (splitVolumes == null) - { - // Split volumes can fail; in this case, we'll export the original solid. - splitVolumes = new List(); - splitVolumes.Add(solid); - } - - return splitVolumes; - } - /// /// Creates IFC curve from curve loop. /// @@ -3698,15 +3642,16 @@ private static bool PointInsidePolygon(UV pnt, IList polyNodes) /// The file /// The exporter /// The curve that needs to convert to IFCCurve - /// indicates whether (TRUE) we want to convert "advanced" curve type - /// like Hermite or NURBS to IfcCurve or (FALSE) we want to tessellate them + /// If true, don't tessellate non-lines and non-arcs. /// A map of already created cartesian points, to avoid duplication. - /// True if we are trimming the generated curve, false otherwise. + /// An indication of how to create the curve. /// The handle representing the IFCCurve /// This cartesianPoints map caches certain 3D points computed by this function that are related to the /// curve, such as the start point of a line and the center of an arc. It uses the cached values when possible. - public static IFCAnyHandle CreateIFCCurveFromRevitCurve(IFCFile file, ExporterIFC exporterIFC, Curve curve, bool allowAdvancedCurve, - IDictionary cartesianPoints, bool useTrimmedCurve, Transform additionalTrf = null) + public static IFCAnyHandle CreateIFCCurveFromRevitCurve(IFCFile file, + ExporterIFC exporterIFC, Curve curve, bool allowAdvancedCurve, + IDictionary cartesianPoints, + TrimCurvePreference trimCurvePreference, Transform additionalTrf) { IFCAnyHandle ifcCurve = null; @@ -3733,24 +3678,27 @@ private static bool PointInsidePolygon(UV pnt, IList polyNodes) if (curve.IsBound) { Line curveLine = curve as Line; - //ifcCurve = CreateLineSegment(exporterIFC, curveLine); + if (trimCurvePreference == TrimCurvePreference.UsePolyLineOrTrim) + { + ifcCurve = CreateLineSegment(exporterIFC, curveLine); + } + else + { + // Create line based trimmed curve for Axis + IFCAnyHandle curveOrigin = XYZtoIfcCartesianPoint(exporterIFC, curveLine.Origin, cartesianPoints, additionalTrf); + XYZ dir = (additionalTrf == null) ? curveLine.Direction : additionalTrf.OfVector(curveLine.Direction); + IFCAnyHandle vector = VectorToIfcVector(exporterIFC, dir); + ifcCurve = IFCInstanceExporter.CreateLine(file, curveOrigin, vector); - // Create line based trimmed curve for Axis - IFCAnyHandle curveOrigin = XYZtoIfcCartesianPoint(exporterIFC, curveLine.Origin, cartesianPoints, additionalTrf); - XYZ dir = (additionalTrf == null) ? curveLine.Direction : additionalTrf.OfVector(curveLine.Direction); - IFCAnyHandle vector = VectorToIfcVector(exporterIFC, curveLine.Direction); - ifcCurve = IFCInstanceExporter.CreateLine(file, curveOrigin, vector); + if (trimCurvePreference == TrimCurvePreference.TrimmedCurve) + { + IFCAnyHandle startPoint = XYZtoIfcCartesianPoint(exporterIFC, curveLine.GetEndPoint(0), cartesianPoints, additionalTrf); + HashSet trim1 = new HashSet() { IFCData.CreateIFCAnyHandle(startPoint) }; + IFCAnyHandle endPoint = XYZtoIfcCartesianPoint(exporterIFC, curveLine.GetEndPoint(1), cartesianPoints, additionalTrf); + HashSet trim2 = new HashSet() { IFCData.CreateIFCAnyHandle(endPoint) }; - if (useTrimmedCurve) - { - IFCAnyHandle startPoint = XYZtoIfcCartesianPoint(exporterIFC, curveLine.GetEndPoint(0), cartesianPoints, additionalTrf); - HashSet trim1 = new HashSet(); - trim1.Add(IFCData.CreateIFCAnyHandle(startPoint)); - IFCAnyHandle endPoint = XYZtoIfcCartesianPoint(exporterIFC, curveLine.GetEndPoint(1), cartesianPoints, additionalTrf); - HashSet trim2 = new HashSet(); - trim2.Add(IFCData.CreateIFCAnyHandle(endPoint)); - - ifcCurve = IFCInstanceExporter.CreateTrimmedCurve(file, ifcCurve, trim1, trim2, true, IFCTrimmingPreference.Cartesian); + ifcCurve = IFCInstanceExporter.CreateTrimmedCurve(file, ifcCurve, trim1, trim2, true, IFCTrimmingPreference.Cartesian); + } } } } @@ -3758,6 +3706,12 @@ private static bool PointInsidePolygon(UV pnt, IList polyNodes) else if (curve is Arc) { Arc curveArc = curve as Arc; + double radius = UnitUtil.ScaleLength(curveArc.Radius); + if (!IFCInstanceExporter.ValidateCircle(radius)) + { + return null; + } + // Normal and x direction should be transformed to IFC coordinates before applying additional transform // arc center will be transformed later in XYZtoIfcCartesianPoint XYZ curveArcNormal = ExporterIFCUtils.TransformAndScaleVector(exporterIFC, curveArc.Normal); @@ -3784,17 +3738,15 @@ private static bool PointInsidePolygon(UV pnt, IList polyNodes) IFCAnyHandle refDirection = ExporterUtil.CreateDirection(file, curveArcXDirection); IFCAnyHandle position3D = IFCInstanceExporter.CreateAxis2Placement3D(file, location3D, axis, refDirection); - ifcCurve = IFCInstanceExporter.CreateCircle(file, position3D, UnitUtil.ScaleLength(curveArc.Radius)); + ifcCurve = IFCInstanceExporter.CreateCircle(file, position3D, radius); - if (useTrimmedCurve) + if (trimCurvePreference != TrimCurvePreference.BaseCurve && curve.IsBound) { IFCAnyHandle startPoint = XYZtoIfcCartesianPoint(exporterIFC, curveArc.GetEndPoint(0), cartesianPoints, additionalTrf); - HashSet trim1 = new HashSet(); - trim1.Add(IFCData.CreateIFCAnyHandle(startPoint)); + HashSet trim1 = new HashSet() { IFCData.CreateIFCAnyHandle(startPoint) }; IFCAnyHandle endPoint = XYZtoIfcCartesianPoint(exporterIFC, curveArc.GetEndPoint(1), cartesianPoints, additionalTrf); - HashSet trim2 = new HashSet(); - trim2.Add(IFCData.CreateIFCAnyHandle(endPoint)); + HashSet trim2 = new HashSet() { IFCData.CreateIFCAnyHandle(endPoint) }; ifcCurve = IFCInstanceExporter.CreateTrimmedCurve(file, ifcCurve, trim1, trim2, true, IFCTrimmingPreference.Cartesian); } @@ -3803,6 +3755,13 @@ private static bool PointInsidePolygon(UV pnt, IList polyNodes) else if (curve is Ellipse) { Ellipse curveEllipse = curve as Ellipse; + double semiAxis1 = UnitUtil.ScaleLength(curveEllipse.RadiusX); + double semiAxis2 = UnitUtil.ScaleLength(curveEllipse.RadiusY); + if (!IFCInstanceExporter.ValidateEllipse(semiAxis1, semiAxis2)) + { + return null; + } + // Normal and x direction should be transformed to IFC coordinates before applying additional transform XYZ ellipseNormal = ExporterIFCUtils.TransformAndScaleVector(exporterIFC, curveEllipse.Normal); XYZ ellipseXDirection = ExporterIFCUtils.TransformAndScaleVector(exporterIFC, curveEllipse.XDirection); @@ -3823,17 +3782,15 @@ private static bool PointInsidePolygon(UV pnt, IList polyNodes) IFCAnyHandle position = IFCInstanceExporter.CreateAxis2Placement3D(file, location3D, axis, refDirection); - ifcCurve = IFCInstanceExporter.CreateEllipse(file, position, UnitUtil.ScaleLength(curveEllipse.RadiusX), UnitUtil.ScaleLength(curveEllipse.RadiusY)); + ifcCurve = IFCInstanceExporter.CreateEllipse(file, position, semiAxis1, semiAxis2); - if (useTrimmedCurve) + if (trimCurvePreference != TrimCurvePreference.BaseCurve && curve.IsBound) { IFCAnyHandle startPoint = XYZtoIfcCartesianPoint(exporterIFC, curveEllipse.GetEndPoint(0), cartesianPoints, additionalTrf); - HashSet trim1 = new HashSet(); - trim1.Add(IFCData.CreateIFCAnyHandle(startPoint)); + HashSet trim1 = new HashSet() { IFCData.CreateIFCAnyHandle(startPoint) }; IFCAnyHandle endPoint = XYZtoIfcCartesianPoint(exporterIFC, curveEllipse.GetEndPoint(1), cartesianPoints, additionalTrf); - HashSet trim2 = new HashSet(); - trim2.Add(IFCData.CreateIFCAnyHandle(endPoint)); + HashSet trim2 = new HashSet() { IFCData.CreateIFCAnyHandle(endPoint) }; ifcCurve = IFCInstanceExporter.CreateTrimmedCurve(file, ifcCurve, trim1, trim2, true, IFCTrimmingPreference.Cartesian); } @@ -4614,10 +4571,14 @@ public static Transform GetSiteLocalPlacement(Document doc) using (SubTransaction projLocTr = new SubTransaction(doc)) { + projLocTr.Start(); doc.ActiveProjectLocation = projLocation; BasePoint surveyPoint = BasePoint.GetSurveyPoint(doc); BasePoint projectBasePoint = BasePoint.GetProjectBasePoint(doc); + if (surveyPoint == null || projectBasePoint == null) + return trf; + (double svNorthings, double svEastings, double svElevation, double svAngle, double pbNorthings, double pbEastings, double pbElevation, double pbAngle) = OptionsUtil.ProjectLocationInfo(doc, surveyPoint.Position, projectBasePoint.Position); @@ -4665,6 +4626,7 @@ public static Transform GetSiteLocalPlacement(Document doc) break; } } + projLocTr.RollBack(); } return trf; } diff --git a/Source/Revit.IFC.Export/Utility/IFCExportInfoPair.cs b/Source/Revit.IFC.Export/Utility/IFCExportInfoPair.cs index 392b037d..626a89b8 100644 --- a/Source/Revit.IFC.Export/Utility/IFCExportInfoPair.cs +++ b/Source/Revit.IFC.Export/Utility/IFCExportInfoPair.cs @@ -13,7 +13,13 @@ namespace Revit.IFC.Export.Utility public class IFCExportInfoPair { IFCEntityType m_ExportInstance = IFCEntityType.UnKnown; - + + IFCEntityType m_ExportType = IFCEntityType.UnKnown; + + private string m_PredefinedType = null; + + private string m_UserdefinedType = null; + /// /// The IfcEntity for export /// @@ -26,8 +32,6 @@ public IFCEntityType ExportInstance } } - IFCEntityType m_ExportType = IFCEntityType.UnKnown; - /// /// The type for export /// @@ -40,20 +44,25 @@ public IFCEntityType ExportType } } - private string m_ValidatedPredefinedType; /// /// Validated PredefinedType from IfcExportType (or IfcType for the old param), /// or from IFC_EXPORT_ELEMENT*_AS /// - public string ValidatedPredefinedType + public string PredefinedType { get { - return m_ValidatedPredefinedType; + return m_PredefinedType; } set { - string newValidatedPredefinedType = IFCValidateEntry.GetValidIFCPredefinedTypeType(value, "NOTDEFINED", m_ExportInstance.ToString()); + if (string.IsNullOrWhiteSpace(value)) + { + // always set to null if value is null or empty to make it possible indicate that PredefinedType is default + m_PredefinedType = null; + } + + string newValidatedPredefinedType = IFCValidateEntry.GetValidIFCPredefinedType(value, m_ExportInstance.ToString()); if (ExporterUtil.IsNotDefined(newValidatedPredefinedType)) { // if the ExportType is unknown, i.e. Entity without type (e.g. IfcGrid), @@ -61,29 +70,87 @@ public string ValidatedPredefinedType // there are exceptions. if (m_ExportType == IFCEntityType.UnKnown) { - newValidatedPredefinedType = - IFCValidateEntry.GetValidIFCPredefinedTypeType(value, "NOTDEFINED", - IfcSchemaEntityTree.GetTypeNameFromInstanceName(m_ExportInstance.ToString())); + newValidatedPredefinedType = IFCValidateEntry.GetValidIFCPredefinedType(value, IfcSchemaEntityTree.GetTypeNameFromInstanceName(m_ExportInstance.ToString())); } else { - newValidatedPredefinedType = - IFCValidateEntry.GetValidIFCPredefinedTypeType(value, "NOTDEFINED", - m_ExportType.ToString()); + newValidatedPredefinedType = IFCValidateEntry.GetValidIFCPredefinedType(value, m_ExportType.ToString()); } } - m_ValidatedPredefinedType = newValidatedPredefinedType; + m_PredefinedType = newValidatedPredefinedType; + } + } + + /// + /// Gets a value indicating whether the is default. + /// + public bool IsPredefinedTypeDefault + { + get { return string.IsNullOrWhiteSpace(m_PredefinedType); } + } + + /// + /// Retrieves the current , or the NOTDEFINED value + /// if the is default. + /// + /// + /// The value of the property if set; otherwise the NOTDEFINED value. + /// + public string GetPredefinedTypeOrDefault() + { + return GetPredefinedTypeOrDefault("NOTDEFINED"); + } + + /// + /// Retrieves the current , or the specified default value + /// if the is default. + /// + /// + /// A value to return if the is default, by default "NOTDEFINED". + /// + /// + /// The value of the property if set; + /// otherwise the parameter. + /// + public string GetPredefinedTypeOrDefault(string defaultPredefinedType) + { + if (IsPredefinedTypeDefault) + { + return defaultPredefinedType; + } + + return m_PredefinedType; + } + + /// + /// Set the property if property value is not initialized or "NOTDEFINED". + /// + /// A new predefined type value. + public void SetPredefinedTypeIfNotDefined(string predefinedType) + { + if (ExporterUtil.IsNotDefined(m_PredefinedType)) + { + PredefinedType = predefinedType; } } /// - /// Returns if the PreDefinedType is null or "NOTDEFINED". + /// The user-defined type, if the predefined type is set to USERDEFINED. /// - /// True if the PreDefinedType is null or "NOTDEFINED" (case-insensitive), or false otherwise. - public bool HasUndefinedPredefinedType() + public string UserDefinedType { - return (m_ValidatedPredefinedType == null) || - m_ValidatedPredefinedType.Equals("NOTDEFINED", StringComparison.InvariantCultureIgnoreCase); + get + { + if (string.Compare(PredefinedType, "USERDEFINED", StringComparison.InvariantCultureIgnoreCase) == 0) + { + return m_UserdefinedType; + } + return null; + } + set + { + m_UserdefinedType = value; + } } /// @@ -91,33 +158,33 @@ public bool HasUndefinedPredefinedType() /// public IFCExportInfoPair() { - m_ValidatedPredefinedType = null; } /// - /// Initialize the class with the entity and the type + /// Initialize the class with the entity and the type. /// - /// the entity - /// the type + /// The instance entity class. + /// The type entity class. public IFCExportInfoPair(IFCEntityType instance, IFCEntityType type, string predefinedType) { - instance = ElementFilteringUtil.GetValidIFCEntityType(instance); - m_ExportInstance = instance; - - type = ElementFilteringUtil.GetValidIFCEntityType(type); - m_ExportType = type; - - ValidatedPredefinedType = predefinedType; + SetValue(instance, type, predefinedType); } - public IFCExportInfoPair(IFCEntityType entity, string predefinedType = null) + /// + /// Initialize the class with the entity and optional predefinedType and userDefinedType.. + /// + /// The entity class. + /// The optional predefined type. + /// The optional user defined type. + public IFCExportInfoPair(IFCEntityType entity, string predefinedType = null, string userDefinedType = null) { - if (string.IsNullOrEmpty(predefinedType)) - ValidatedPredefinedType = null; - else - ValidatedPredefinedType = predefinedType; + if (!string.IsNullOrEmpty(predefinedType)) + PredefinedType = predefinedType; + + SetByTypeAndPredefinedType(entity, predefinedType); - SetValueWithPair(entity, predefinedType); + if (!string.IsNullOrEmpty(userDefinedType)) + UserDefinedType = userDefinedType; } /// @@ -125,7 +192,7 @@ public IFCExportInfoPair(IFCEntityType entity, string predefinedType = null) /// public bool IsUnKnown { - get { return (m_ExportInstance == IFCEntityType.UnKnown); } + get { return m_ExportInstance == IFCEntityType.UnKnown; } } /// @@ -149,34 +216,32 @@ public void SetValue(IFCEntityType instance, IFCEntityType type, string predefin type = ElementFilteringUtil.GetValidIFCEntityType(type); m_ExportType = type; - ValidatedPredefinedType = predefinedType; + PredefinedType = predefinedType; } /// - /// Set the pair information using only either the entity or the type + /// Set the export type info by given entity type. /// - /// the entity or type - /// predefinedtype string - public void SetValueWithPair(IFCEntityType entityType, string predefineType = null) + /// The entinty type. + public void SetByType(IFCEntityType entityType) { - SetValueWithPair(entityType.ToString(), predefineType); + SetByTypeName(entityType.ToString()); } /// - /// Set the pair information using only either the entity or the type + /// Set the export type info by given entity type name. /// - /// the entity or type string - /// predefinedtype string - public void SetValueWithPair(string entityTypeStr, string predefineType = null) + /// The entinty type name. + public void SetByTypeName(string entityTypeName) { IFCVersion ifcVersion = ExporterCacheManager.ExportOptionsCache.FileVersion; IfcSchemaEntityTree theTree = IfcSchemaEntityTree.GetEntityDictFor(ifcVersion); int typeLen = 4; - bool isType = entityTypeStr.Substring(entityTypeStr.Length - 4, 4).Equals("Type", StringComparison.CurrentCultureIgnoreCase); + bool isType = entityTypeName.EndsWith("Type", StringComparison.CurrentCultureIgnoreCase); if (!isType) { - if (entityTypeStr.Equals("IfcDoorStyle", StringComparison.InvariantCultureIgnoreCase) - || entityTypeStr.Equals("IfcWindowStyle", StringComparison.InvariantCultureIgnoreCase)) + if (entityTypeName.Equals("IfcDoorStyle", StringComparison.InvariantCultureIgnoreCase) + || entityTypeName.Equals("IfcWindowStyle", StringComparison.InvariantCultureIgnoreCase)) { isType = true; typeLen = 5; @@ -186,7 +251,7 @@ public void SetValueWithPair(string entityTypeStr, string predefineType = null) if (isType) { // Get the instance - string instName = entityTypeStr.Substring(0, entityTypeStr.Length - typeLen); + string instName = entityTypeName.Substring(0, entityTypeName.Length - typeLen); IfcSchemaEntityNode node = theTree.Find(instName); if (node != null && !node.isAbstract) { @@ -207,12 +272,12 @@ public void SetValueWithPair(string entityTypeStr, string predefineType = null) } // set the type - IFCEntityType entityType = ElementFilteringUtil.GetValidIFCEntityType(entityTypeStr); + IFCEntityType entityType = ElementFilteringUtil.GetValidIFCEntityType(entityTypeName); if (entityType != IFCEntityType.UnKnown) m_ExportType = entityType; else { - node = IfcSchemaEntityTree.FindNonAbsInstanceSuperType(ifcVersion, entityTypeStr); + node = IfcSchemaEntityTree.FindNonAbsInstanceSuperType(ifcVersion, entityTypeName); if (node != null) { IFCEntityType instType = IFCEntityType.UnKnown; @@ -224,13 +289,13 @@ public void SetValueWithPair(string entityTypeStr, string predefineType = null) else { // set the instance - IFCEntityType instType = ElementFilteringUtil.GetValidIFCEntityType(entityTypeStr); + IFCEntityType instType = ElementFilteringUtil.GetValidIFCEntityType(entityTypeName); if (instType != IFCEntityType.UnKnown) m_ExportInstance = instType; else { // If not found, try non-abstract supertype derived from the type - IfcSchemaEntityNode node = IfcSchemaEntityTree.FindNonAbsInstanceSuperType(ifcVersion, entityTypeStr); + IfcSchemaEntityNode node = IfcSchemaEntityTree.FindNonAbsInstanceSuperType(ifcVersion, entityTypeName); if (node != null) { instType = IFCEntityType.UnKnown; @@ -240,10 +305,10 @@ public void SetValueWithPair(string entityTypeStr, string predefineType = null) } // set the type pair - string typeName = entityTypeStr; + string typeName = entityTypeName; if (ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4 && - (entityTypeStr.Equals("IfcDoor", StringComparison.InvariantCultureIgnoreCase) - || entityTypeStr.Equals("IfcWindow", StringComparison.InvariantCultureIgnoreCase))) + (entityTypeName.Equals("IfcDoor", StringComparison.InvariantCultureIgnoreCase) + || entityTypeName.Equals("IfcWindow", StringComparison.InvariantCultureIgnoreCase))) typeName += "Style"; else typeName += "Type"; @@ -256,7 +321,7 @@ public void SetValueWithPair(string entityTypeStr, string predefineType = null) { // If the type name is not found, likely it does not have the pair at this level, // needs to get the supertype of the instance to get the type pair - IList instNodes = IfcSchemaEntityTree.FindAllSuperTypes(ifcVersion, entityTypeStr, "IfcProduct", "IfcGroup"); + IList instNodes = IfcSchemaEntityTree.FindAllSuperTypes(ifcVersion, entityTypeName, "IfcProduct", "IfcGroup"); foreach (IfcSchemaEntityNode instNode in instNodes) { typeName = IfcSchemaEntityTree.GetTypeNameFromInstanceName(instNode.Name); @@ -276,8 +341,18 @@ public void SetValueWithPair(string entityTypeStr, string predefineType = null) } } } + } + + /// + /// Set the export type info by given entity type and predefined type. + /// + /// The entinty type. + /// The PredefinedType attribute value. + public void SetByTypeAndPredefinedType(IFCEntityType entityType, string predefinedTypeName) + { + SetByType(entityType); - ValidatedPredefinedType = predefineType; + PredefinedType = predefinedTypeName; } // Check valid entity and type set according to the MVD used in the export @@ -300,14 +375,14 @@ void CheckValidEntity() IFCEntityType newInst; if (Enum.TryParse(newInstanceName, true, out newInst)) //m_ExportInstance = newInst; - SetValueWithPair(newInst); + SetByType(newInst); } else if (m_ExportInstance.ToString().EndsWith("ElementedCase", StringComparison.InvariantCultureIgnoreCase)) { string newInstanceName = m_ExportInstance.ToString().Remove(m_ExportInstance.ToString().Length - 13); IFCEntityType newInst; if (Enum.TryParse(newInstanceName, true, out newInst)) - SetValueWithPair(newInst); + SetByType(newInst); } } diff --git a/Source/Revit.IFC.Export/Utility/LevelInfoCache.cs b/Source/Revit.IFC.Export/Utility/LevelInfoCache.cs index ef1f04e4..1031840d 100644 --- a/Source/Revit.IFC.Export/Utility/LevelInfoCache.cs +++ b/Source/Revit.IFC.Export/Utility/LevelInfoCache.cs @@ -18,6 +18,8 @@ // using System.Collections.Generic; +using System.Collections.Immutable; +using System.Diagnostics; using System.Linq; using Autodesk.Revit.DB; using Autodesk.Revit.DB.IFC; @@ -204,6 +206,33 @@ public void AddLevelInfo(ExporterIFC exporterIFC, ElementId levelId, IFCLevelInf exporterIFC.AddBuildingStorey(levelId, info); } + /// + /// Clears all caches. + /// + /// The Exporter object. + public void Clear(ExporterIFC exporterIFC) + { + // Clear data stored externally to LevelInfoCache. + if (exporterIFC != null) + { + ISet uniqueLevels = LevelsByElevation?.ToHashSet(); + if ((uniqueLevels?.Count ?? 0) > 0) + { + foreach (ElementId levelId in uniqueLevels) + { + exporterIFC.RemoveBuildingStorey(levelId); + } + } + } + + // Revert all caches back to original state. + m_ElementIdToLevelHeight?.Clear(); + m_BuildingStoriesByElevation?.Clear(); + m_LevelsByElevation?.Clear(); + m_OrphanedElements?.Clear(); + m_OrphanedSpaces?.Clear(); + FloorSlabEdgeLevels = null; + } /// /// Get the IFCLevelInfo corresponding to a level. diff --git a/Source/Revit.IFC.Export/Utility/MEPCache.cs b/Source/Revit.IFC.Export/Utility/MEPCache.cs index 99ce3283..61ebe448 100644 --- a/Source/Revit.IFC.Export/Utility/MEPCache.cs +++ b/Source/Revit.IFC.Export/Utility/MEPCache.cs @@ -41,9 +41,9 @@ public class MEPCache public List MEPConnectors = new List(); /// - /// A cache of elements (Ducts and Pipes) that may have coverings (Linings and/or Insulations). + /// A cache of elements (Ducts and Pipes) that may have coverings (Linings and/or Insulations) and their categories. /// - public HashSet CoveredElementsCache = new HashSet(); + public IDictionary CoveredElementsCache = new Dictionary(); /// /// A cache of elements (Cable Trays and Conduits) that may be assigned to systems diff --git a/Source/Revit.IFC.Export/Utility/MaterialLayerSetInfo.cs b/Source/Revit.IFC.Export/Utility/MaterialLayerSetInfo.cs index be5a4c9b..f778c624 100644 --- a/Source/Revit.IFC.Export/Utility/MaterialLayerSetInfo.cs +++ b/Source/Revit.IFC.Export/Utility/MaterialLayerSetInfo.cs @@ -15,21 +15,33 @@ public class MaterialInfo { public MaterialInfo(ElementId baseMatId, string layerName, double matWidth, MaterialFunctionAssignment function) { - m_baseMatId = baseMatId; - m_layerName = layerName; - m_matWidth = matWidth; - m_function = function; + BaseMatId = baseMatId; + LayerName = layerName; + ShapeAspectName = layerName; + Width = matWidth; + Function = function; } - public ElementId m_baseMatId; - public string m_layerName; - public double m_matWidth; - public MaterialFunctionAssignment m_function; + + public ElementId BaseMatId { get; private set; } = ElementId.InvalidElementId; + + public string LayerName { get; private set; } = null; + + public string ShapeAspectName { get; set; } = null; + + public double Width { get; set; } = 0.0; + + public MaterialFunctionAssignment Function { get; private set; } = MaterialFunctionAssignment.None; } - ExporterIFC m_ExporterIFC; - Element m_Element; - ProductWrapper m_ProductWrapper; - GeometryElement m_GeometryElement = null; - bool m_needToGenerateIFCObjects = false; + + private ExporterIFC ExporterIFC { get; set; } = null; + + private Element Element { get; set; } = null; + + private ProductWrapper ProductWrapper { get; set; } = null; + + private GeometryElement GeometryElement { get; set; } = null; + + bool NeedToGenerateIFCObjects { get; set; } = false; /// /// Initialize MaterialLayerSetInfo for element @@ -39,10 +51,10 @@ public MaterialInfo(ElementId baseMatId, string layerName, double matWidth, Mate /// the product wrapper public MaterialLayerSetInfo(ExporterIFC exporterIFC, Element element, ProductWrapper productWrapper, GeometryElement geometryElement = null) { - m_Element = element; - m_ExporterIFC = exporterIFC; - m_ProductWrapper = productWrapper; - m_GeometryElement = geometryElement; + Element = element; + ExporterIFC = exporterIFC; + ProductWrapper = productWrapper; + GeometryElement = geometryElement; CollectMaterialLayerSet(); } @@ -50,7 +62,7 @@ public void SingleMaterialOverride (ElementId materialId, double materialWidth) { GenerateIFCObjectsIfNeeded(); - Material material = m_Element.Document.GetElement(materialId) as Material; + Material material = Element.Document.GetElement(materialId) as Material; string layerName = "Layer"; if (material != null) { @@ -59,9 +71,9 @@ public void SingleMaterialOverride (ElementId materialId, double materialWidth) MaterialInfo matInfo = new MaterialInfo(materialId, layerName, materialWidth, MaterialFunctionAssignment.None); MaterialIds.Add(matInfo); - IFCAnyHandle singleMaterialOverrideHnd = IFCInstanceExporter.CreateMaterial(m_ExporterIFC.GetFile(), layerName, null, null); - ExporterCacheManager.MaterialHandleCache.Register(MaterialIds[0].m_baseMatId, singleMaterialOverrideHnd); - m_MaterialLayerSetHandle = singleMaterialOverrideHnd; + IFCAnyHandle singleMaterialOverrideHnd = IFCInstanceExporter.CreateMaterial(ExporterIFC.GetFile(), layerName, null, null); + ExporterCacheManager.MaterialHandleCache.Register(MaterialIds[0].BaseMatId, singleMaterialOverrideHnd); + m_GeneratedMaterialLayerSetHandle = singleMaterialOverrideHnd; } /// @@ -71,7 +83,7 @@ public bool IsEmpty { get { - return (m_MaterialLayerSetHandle == null && MaterialIds.Count == 0); + return (m_GeneratedMaterialLayerSetHandle == null && MaterialIds.Count == 0); } } @@ -85,14 +97,14 @@ public bool IsEmpty /// Warning: Do not call Properties inside class because this can break lazy generation of IFC objects. /// Use private members instead. /// - private IFCAnyHandle m_MaterialLayerSetHandle = null; + private IFCAnyHandle m_GeneratedMaterialLayerSetHandle = null; public IFCAnyHandle MaterialLayerSetHandle { get { GenerateIFCObjectsIfNeeded(); - return m_MaterialLayerSetHandle; + return m_GeneratedMaterialLayerSetHandle; } } @@ -101,14 +113,15 @@ public IFCAnyHandle MaterialLayerSetHandle /// Warning: Do not call Properties inside class because this can break lazy generation of IFC objects. /// Use private members instead. /// - private IFCAnyHandle m_PrimaryMaterialHandle = null; + private IFCAnyHandle m_GeneratedPrimaryMaterialHandle = null; + public IFCAnyHandle PrimaryMaterialHandle { get { GenerateIFCObjectsIfNeeded(); - return m_PrimaryMaterialHandle; + return m_GeneratedPrimaryMaterialHandle; } } @@ -117,14 +130,15 @@ public IFCAnyHandle PrimaryMaterialHandle /// Warning: Do not call Properties inside class because this can break lazy generation of IFC objects. /// Use private members instead. /// - private HashSet m_LayerQuantityWidthHnd = new HashSet(); + private HashSet m_GeneratedLayerQuantityWidthHnd = new HashSet(); + public HashSet LayerQuantityWidthHnd { get { GenerateIFCObjectsIfNeeded(); - return m_LayerQuantityWidthHnd; + return m_GeneratedLayerQuantityWidthHnd; } } @@ -141,10 +155,10 @@ public HashSet LayerQuantityWidthHnd /// private void CollectMaterialLayerSet() { - ElementId typeElemId = m_Element.GetTypeId(); + ElementId typeElemId = Element.GetTypeId(); IFCAnyHandle materialLayerSet = ExporterCacheManager.MaterialSetCache.FindLayerSet(typeElemId); // Roofs with no components are only allowed one material. We will arbitrarily choose the thickest material. - m_PrimaryMaterialHandle = ExporterCacheManager.MaterialSetCache.FindPrimaryMaterialHnd(typeElemId); + m_GeneratedPrimaryMaterialHandle = ExporterCacheManager.MaterialSetCache.FindPrimaryMaterialHnd(typeElemId); bool materialHandleIsNotValid = IFCAnyHandleUtil.IsNullOrHasNoValue(materialLayerSet); if (IFCAnyHandleUtil.IsNullOrHasNoValue(materialLayerSet) || materialHandleIsNotValid) @@ -153,23 +167,23 @@ private void CollectMaterialLayerSet() { UnregisterIFCHandles(); } - m_needToGenerateIFCObjects = true; + NeedToGenerateIFCObjects = true; List widths = new List(); List functions = new List(); - HostObjAttributes hostObjAttr = m_Element.Document.GetElement(typeElemId) as HostObjAttributes; + HostObjAttributes hostObjAttr = Element.Document.GetElement(typeElemId) as HostObjAttributes; if (hostObjAttr == null) { // It does not have the HostObjAttribute (where we will get the compound structure for material layer set. // We will define a single material instead and create the material layer set of this single material if there is enough information (At least Material id and thickness) - FamilyInstance familyInstance = m_Element as FamilyInstance; + FamilyInstance familyInstance = Element as FamilyInstance; if (familyInstance == null) { - if (m_GeometryElement != null) + if (GeometryElement != null) { - ElementId matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(m_GeometryElement, m_Element); - CategoryUtil.CreateMaterialAssociation(m_ExporterIFC, m_ProductWrapper.GetAnElement(), matId); + ElementId matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(GeometryElement, Element); + CategoryUtil.CreateMaterialAssociation(ExporterIFC, ProductWrapper.GetAnElement(), matId); } return; } @@ -179,8 +193,8 @@ private void CollectMaterialLayerSet() if (famMatIds.Count == 0) { // For some reason Plate type may not return any Material id - ElementId baseMatId = CategoryUtil.GetBaseMaterialIdForElement(m_Element); - Material material = m_Element.Document.GetElement(baseMatId) as Material; + ElementId baseMatId = CategoryUtil.GetBaseMaterialIdForElement(Element); + Material material = Element.Document.GetElement(baseMatId) as Material; if (material == null) return; @@ -209,10 +223,10 @@ private void CollectMaterialLayerSet() continue; widths.Add(matWidth); - ElementId baseMatId = CategoryUtil.GetBaseMaterialIdForElement(m_Element); + ElementId baseMatId = CategoryUtil.GetBaseMaterialIdForElement(Element); if (matid != ElementId.InvalidElementId) { - Material material = m_Element.Document.GetElement(matid) as Material; + Material material = Element.Document.GetElement(matid) as Material; if (material != null) { string layerName = NamingUtil.GetMaterialLayerName(material); @@ -230,13 +244,13 @@ private void CollectMaterialLayerSet() } else { - ElementId baseMatId = CategoryUtil.GetBaseMaterialIdForElement(m_Element); + ElementId baseMatId = CategoryUtil.GetBaseMaterialIdForElement(Element); CompoundStructure cs = hostObjAttr.GetCompoundStructure(); if (cs != null) { double scaledOffset = 0.0, scaledWallWidth = 0.0, wallHeight = 0.0; - Wall wall = m_Element as Wall; + Wall wall = Element as Wall; if (wall != null) { scaledWallWidth = UnitUtil.ScaleLength(wall.Width); @@ -262,7 +276,7 @@ private void CollectMaterialLayerSet() if (matId != ElementId.InvalidElementId) { - Material material = m_Element.Document.GetElement(matId) as Material; + Material material = Element.Document.GetElement(matId) as Material; if (material != null) { string layerName = NamingUtil.GetMaterialLayerName(material); @@ -282,7 +296,7 @@ private void CollectMaterialLayerSet() widths.Add(matWidth); if (baseMatId != ElementId.InvalidElementId) { - Material material = m_Element.Document.GetElement(baseMatId) as Material; + Material material = Element.Document.GetElement(baseMatId) as Material; if (material != null) { string layerName = NamingUtil.GetMaterialLayerName(material); @@ -296,16 +310,16 @@ private void CollectMaterialLayerSet() } else { - m_needToGenerateIFCObjects = false; + NeedToGenerateIFCObjects = false; - m_MaterialLayerSetHandle = materialLayerSet; + m_GeneratedMaterialLayerSetHandle = materialLayerSet; MaterialLayerSetInfo mlsInfo = ExporterCacheManager.MaterialSetCache.FindMaterialLayerSetInfo(typeElemId); if (mlsInfo != null) { MaterialIds = mlsInfo.MaterialIds; - m_PrimaryMaterialHandle = mlsInfo.PrimaryMaterialHandle; - m_LayerQuantityWidthHnd = mlsInfo.LayerQuantityWidthHnd; + m_GeneratedPrimaryMaterialHandle = mlsInfo.PrimaryMaterialHandle; + m_GeneratedLayerQuantityWidthHnd = mlsInfo.LayerQuantityWidthHnd; TotalThickness = mlsInfo.TotalThickness; } } @@ -315,16 +329,16 @@ private void CollectMaterialLayerSet() private void GenerateIFCObjectsIfNeeded() { - if (!m_needToGenerateIFCObjects) + if (!NeedToGenerateIFCObjects) return; - m_needToGenerateIFCObjects = false; + NeedToGenerateIFCObjects = false; IFCAnyHandle materialLayerSet = null; - if (m_ProductWrapper != null && !m_ProductWrapper.ToNative().IsValidObject) - m_ProductWrapper = null; + if (ProductWrapper != null && !ProductWrapper.ToNative().IsValidObject) + ProductWrapper = null; - m_ProductWrapper?.ClearFinishMaterials(); + ProductWrapper?.ClearFinishMaterials(); // We can't create IfcMaterialLayers without creating an IfcMaterialLayerSet. So we will simply collate here. IList materialHnds = new List(); @@ -333,59 +347,61 @@ private void GenerateIFCObjectsIfNeeded() for (int ii = 0; ii < MaterialIds.Count; ++ii) { // Require positive width for IFC2x3 and before, and non-negative width for IFC4. - if (MaterialIds[ii].m_matWidth < -MathUtil.Eps()) + if (MaterialIds[ii].Width < -MathUtil.Eps()) continue; - bool almostZeroWidth = MathUtil.IsAlmostZero(MaterialIds[ii].m_matWidth); + bool almostZeroWidth = MathUtil.IsAlmostZero(MaterialIds[ii].Width); if (ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4 && almostZeroWidth) continue; if (almostZeroWidth) - MaterialIds[ii].m_matWidth = 0.0; + { + MaterialIds[ii].Width = 0.0; + } - IFCAnyHandle materialHnd = CategoryUtil.GetOrCreateMaterialHandle(m_ExporterIFC, MaterialIds[ii].m_baseMatId); - if (m_PrimaryMaterialHandle == null || (MaterialIds[ii].m_matWidth > thickestLayer)) + IFCAnyHandle materialHnd = CategoryUtil.GetOrCreateMaterialHandle(ExporterIFC, MaterialIds[ii].BaseMatId); + if (m_GeneratedPrimaryMaterialHandle == null || (MaterialIds[ii].Width > thickestLayer)) { - m_PrimaryMaterialHandle = materialHnd; - thickestLayer = MaterialIds[ii].m_matWidth; + m_GeneratedPrimaryMaterialHandle = materialHnd; + thickestLayer = MaterialIds[ii].Width; } widthIndices.Add(ii); materialHnds.Add(materialHnd); - if ((m_ProductWrapper != null) && (MaterialIds[ii].m_function == MaterialFunctionAssignment.Finish1 || MaterialIds[ii].m_function == MaterialFunctionAssignment.Finish2)) + if ((ProductWrapper != null) && (MaterialIds[ii].Function == MaterialFunctionAssignment.Finish1 || MaterialIds[ii].Function == MaterialFunctionAssignment.Finish2)) { - m_ProductWrapper.AddFinishMaterial(materialHnd); + ProductWrapper.AddFinishMaterial(materialHnd); } } int numLayersToCreate = widthIndices.Count; if (numLayersToCreate == 0) { - m_MaterialLayerSetHandle = materialLayerSet; + m_GeneratedMaterialLayerSetHandle = materialLayerSet; return; } // If it is a single material, check single material override (only IfcMaterial without IfcMaterialLayerSet with only 1 member) if (numLayersToCreate == 1 && ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView) { - m_MaterialLayerSetHandle = ExporterUtil.GetSingleMaterial(m_ExporterIFC, m_Element, - MaterialIds[0].m_baseMatId) ?? materialHnds[0]; + m_GeneratedMaterialLayerSetHandle = ExporterUtil.GetSingleMaterial(ExporterIFC, Element, + MaterialIds[0].BaseMatId) ?? materialHnds[0]; return; } - IFCFile file = m_ExporterIFC.GetFile(); + IFCFile file = ExporterIFC.GetFile(); Document document = ExporterCacheManager.Document; IList layers = new List(numLayersToCreate); IList> layerWidthQuantities = new List>(); - var uniqueNames = new Dictionary<(string, double), string>(new NameAndWidthComparer()); + HashSet layerNameUsed = new HashSet(); double totalWidth = 0.0; for (int ii = 0; ii < numLayersToCreate; ii++) { int widthIndex = widthIndices[ii]; - double scaledWidth = UnitUtil.ScaleLength(MaterialIds[widthIndex].m_matWidth); + double scaledWidth = UnitUtil.ScaleLength(MaterialIds[widthIndex].Width); string layerName = "Layer"; string description = null; @@ -395,7 +411,7 @@ private void GenerateIFCObjectsIfNeeded() IFCLogical? isVentilated = null; int isVentilatedValue; - Material material = document.GetElement(MaterialIds[ii].m_baseMatId) as Material; + Material material = document.GetElement(MaterialIds[ii].BaseMatId) as Material; if (material != null) { if (ParameterUtil.GetIntValueFromElement(material, "IfcMaterialLayer.IsVentilated", out isVentilatedValue) != null) @@ -408,14 +424,11 @@ private void GenerateIFCObjectsIfNeeded() if (!ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4) { - layerName = MaterialIds[ii].m_layerName; + layerName = MaterialIds[ii].ShapeAspectName; if (string.IsNullOrEmpty(layerName)) layerName = "Layer"; - // Ensure layer name is unique for different layer widths - layerName = GetUniqueMaterialNameWithWidth(layerName, scaledWidth, uniqueNames); - - description = NamingUtil.GetOverrideStringValue(material, "IfcMaterialLayer.Description", + description = NamingUtil.GetOverrideStringValue(material, "IfcMaterialLayer.Description", IFCAnyHandleUtil.GetStringAttribute(materialHnds[ii], "Description")); category = NamingUtil.GetOverrideStringValue(material, "IfcMaterialLayer.Category", IFCAnyHandleUtil.GetStringAttribute(materialHnds[ii], "Category")); @@ -447,7 +460,7 @@ private void GenerateIFCObjectsIfNeeded() } } - ElementId typeElemId = m_Element.GetTypeId(); + ElementId typeElemId = Element.GetTypeId(); if (layers.Count > 0) { ElementType type = document.GetElement(typeElemId) as ElementType; @@ -458,41 +471,41 @@ private void GenerateIFCObjectsIfNeeded() if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView) { HashSet constituents = new HashSet(layers); - m_MaterialLayerSetHandle = CategoryUtil.GetOrCreateMaterialConstituentSet(file, + m_GeneratedMaterialLayerSetHandle = CategoryUtil.GetOrCreateMaterialConstituentSet(file, typeElemId, null, constituents, layerSetName, layerSetDesc); foreach (Tuple layerWidthQty in layerWidthQuantities) { - m_LayerQuantityWidthHnd.Add(IFCInstanceExporter.CreatePhysicalComplexQuantity(file, layerWidthQty.Item1, null, + m_GeneratedLayerQuantityWidthHnd.Add(IFCInstanceExporter.CreatePhysicalComplexQuantity(file, layerWidthQty.Item1, null, new HashSet() { layerWidthQty.Item2 }, "Layer", null, null)); } // Finally create the total width as a quantity - m_LayerQuantityWidthHnd.Add(IFCInstanceExporter.CreateQuantityLength(file, "Width", null, null, totalWidth)); + m_GeneratedLayerQuantityWidthHnd.Add(IFCInstanceExporter.CreateQuantityLength(file, "Width", null, null, totalWidth)); } else { - m_MaterialLayerSetHandle = IFCInstanceExporter.CreateMaterialLayerSet(file, layers, layerSetName, layerSetDesc); + m_GeneratedMaterialLayerSetHandle = IFCInstanceExporter.CreateMaterialLayerSet(file, layers, layerSetName, layerSetDesc); } - ExporterCacheManager.MaterialSetCache.RegisterLayerSet(typeElemId, m_MaterialLayerSetHandle, this); + ExporterCacheManager.MaterialSetCache.RegisterLayerSet(typeElemId, m_GeneratedMaterialLayerSetHandle, this); } - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(m_PrimaryMaterialHandle)) - ExporterCacheManager.MaterialSetCache.RegisterPrimaryMaterialHnd(typeElemId, m_PrimaryMaterialHandle); + if (!IFCAnyHandleUtil.IsNullOrHasNoValue(m_GeneratedPrimaryMaterialHandle)) + ExporterCacheManager.MaterialSetCache.RegisterPrimaryMaterialHnd(typeElemId, m_GeneratedPrimaryMaterialHandle); } private void UnregisterIFCHandles() { - ElementId typeElemId = m_Element.GetTypeId(); + ElementId typeElemId = Element.GetTypeId(); ExporterCacheManager.MaterialSetCache.UnregisterLayerSet(typeElemId); ExporterCacheManager.MaterialSetCache.UnregisterPrimaryMaterialHnd(typeElemId); - if (m_ProductWrapper != null) - m_ProductWrapper.ClearFinishMaterials(); + if (ProductWrapper != null) + ProductWrapper.ClearFinishMaterials(); - m_MaterialLayerSetHandle = null; - m_PrimaryMaterialHandle = null; - m_LayerQuantityWidthHnd.Clear(); + m_GeneratedMaterialLayerSetHandle = null; + m_GeneratedPrimaryMaterialHandle = null; + m_GeneratedLayerQuantityWidthHnd.Clear(); } public enum CompareTwoLists @@ -518,41 +531,5 @@ public static CompareTwoLists CompareMaterialInfoList(IList materialL return CompareTwoLists.ListsUnequal; } - - public class NameAndWidthComparer : IEqualityComparer<(string, double)> - { - public bool Equals((string, double) tup1, (string, double) tup2) - { - return tup1.Item1.Equals(tup2.Item1, StringComparison.Ordinal) && MathUtil.IsAlmostEqual(tup1.Item2, tup2.Item2); - } - - public int GetHashCode((string, double) tup) - { - int hashCode = tup.Item1.GetHashCode() ^ tup.Item2.GetHashCode(); - return hashCode; - } - } - - /// - /// Returns the unique name for material name and width pair checking within the given collection. - /// - /// the input name - /// the input width - /// the collection where the name should be search - /// the unique name - public static string GetUniqueMaterialNameWithWidth(string originalName, double width, IDictionary<(string name, double width), string> uniqueNames) - { - if (originalName == null) - return null; - - string uniqueName = string.Empty; - if (uniqueNames.TryGetValue((originalName, width), out uniqueName)) - return uniqueName; - - string newName = NamingUtil.GetUniqueNameWithinSet(originalName, uniqueNames.Values.ToHashSet()); - uniqueNames.Add((originalName, width), newName); - - return newName; - } } } diff --git a/Source/Revit.IFC.Export/Utility/NamingUtil.cs b/Source/Revit.IFC.Export/Utility/NamingUtil.cs index 9a421780..d0b889af 100644 --- a/Source/Revit.IFC.Export/Utility/NamingUtil.cs +++ b/Source/Revit.IFC.Export/Utility/NamingUtil.cs @@ -371,10 +371,11 @@ public static string GetObjectTypeOverride(Element element, string originalValue // ObjectType attribute will be overridden by that value, allowing ObjectType is set according to the Type setting // such as IfcExportType="USERDEFINED" set in the Type which necessitates ObjectType in the instance to be set to // the appropriate value + Element typeOrSymbol = null; if (string.IsNullOrEmpty(overrideValue) || (!string.IsNullOrEmpty(overrideValue) && overrideValue.Equals(originalValue))) { - Element typeOrSymbol = element.Document.GetElement(element.GetTypeId()) as ElementType; ; + typeOrSymbol = element.Document.GetElement(element.GetTypeId()) as ElementType; if (typeOrSymbol == null) { FamilyInstance famInst = element as FamilyInstance; @@ -388,6 +389,21 @@ public static string GetObjectTypeOverride(Element element, string originalValue overrideValue = GetOverrideStringValue(typeOrSymbol, objectTypeOverride, originalValue); } } + + if (string.IsNullOrEmpty(overrideValue) + || (!string.IsNullOrEmpty(overrideValue) && overrideValue.Equals(originalValue))) + { + Document document = element.Document; + ElementId categoryId = element?.Category?.Id ?? ElementId.InvalidElementId; + CustomSubCategoryId customSubCategoryId = + ExporterUtil.WallFunctionToCustomSubCategoryId((typeOrSymbol as WallType)?.Function); + ExportIFCCategoryInfo info = ExporterCacheManager.CategoryMappingTemplate.GetMappingInfoById(document, categoryId, customSubCategoryId); + if (string.Compare(info?.IFCPredefinedType ?? string.Empty, "USERDEFINED", true) == 0) + { + overrideValue = info.IFCUserDefinedType; + } + } + //GetOverrideStringValue will return the override value from the parameter specified, otherwise it will return the originalValue return overrideValue; } diff --git a/Source/Revit.IFC.Export/Utility/OpeningUtil.cs b/Source/Revit.IFC.Export/Utility/OpeningUtil.cs index 9be4c61e..59a65aa1 100644 --- a/Source/Revit.IFC.Export/Utility/OpeningUtil.cs +++ b/Source/Revit.IFC.Export/Utility/OpeningUtil.cs @@ -152,7 +152,7 @@ class OpeningUtil Transform offsetTransform, ExporterIFC exporterIFC, IFCAnyHandle originalPlacement, PlacementSetter setter, ProductWrapper wrapper) { - if (IFCAnyHandleUtil.IsNullOrHasNoValue(elementHandle)) + if (IFCAnyHandleUtil.IsNullOrHasNoValue(elementHandle) || extraParams == null) return; ElementId categoryId = CategoryUtil.GetSafeCategoryId(element); @@ -268,7 +268,7 @@ public static bool NeedToCreateOpenings(IFCAnyHandle elementHandle, IFCExportBod // including a line as part of the elevation profile of the wall. // As such, we will restrict which element types we check for CanExportElement. if ((openingElem is WallSweep) && - (!ElementFilteringUtil.CanExportElement(exporterIFC, openingElem, true))) + (!ElementFilteringUtil.CanExportElement(openingElem, true))) continue; IList extrusionDataList = openingData.GetExtrusionData(); @@ -292,7 +292,7 @@ public static bool NeedToCreateOpenings(IFCAnyHandle elementHandle, IFCExportBod element.Id, parentHandle, setter.LevelId); if (delayedCreator != null) { - ExporterCacheManager.DoorWindowDelayedOpeningCreatorCache.Add(delayedCreator); + ExporterCacheManager.DoorWindowDelayedOpeningCreatorCache.Add(delayedCreator, true); continue; } } diff --git a/Source/Revit.IFC.Export/Utility/ParamExprResolverParser.g4 b/Source/Revit.IFC.Export/Utility/ParamExprResolverParser.g4 index b768ab23..b52c274e 100644 --- a/Source/Revit.IFC.Export/Utility/ParamExprResolverParser.g4 +++ b/Source/Revit.IFC.Export/Utility/ParamExprResolverParser.g4 @@ -5,8 +5,10 @@ grammar ParamExprResolverParser; @lexer::members { - public static int WHITESPACE = 1; - public static int COMMENTS = 2; +// NOTE: If WHITESPACE is changed from 1, please also change the following line below: +// WS: [ \t\n\r]+ -> channel(1) ; +// This is hardwired to 1 (instead of WHITESPACE) to avoid a compiler warning. + public const int WHITESPACE = 1; } /* @@ -20,10 +22,12 @@ expr: value | expr ops expr | '(' expr ')' (power_op)? ; -param_name: NAMEWITHSPECIALCHAR+; +param_name: NAMEWITHSPECIALCHAR_EXPLICIT+; unary_operator: '+' | '-' ; ops: MULTIPLY | DIVIDE | ADDITION | SUBTRACT ; -power_op: '^' ( '-' | '+' )? INT; +INT_DIGIT: INT; +NAMEWITHSPECIALCHAR_EXPLICIT: NAMEWITHSPECIALCHAR; +power_op: '^' ( '-' | '+' )? INT_DIGIT; value: realliteral | stringliteral ; stringliteral: STRING ; realliteral: signed_number ; @@ -42,15 +46,23 @@ DIVIDE: '/'; ADDITION: '+'; SUBTRACT: '-'; -STRING : ( . )*? ; +STRING : (['] (ESC | .)*? [']) + | (["] (ESC | .)*? ["]); NUMBER: INT '.' INT? EXP? // 1.35, 1.35E-9, 0.3 | '.' INT EXP? // .2, .2e-9 | INT EXP? // 1e10 | INT // 45 ; fragment ALPHANUMERIC: [a-zA-Z0-9_] ; -fragment NAMEWITHSPECIALCHAR: [a-zA-Z0-9&*%^$#@!_=+-/.,"']; +fragment NAMEWITHSPECIALCHAR: [a-zA-Z0-9&*%^$#@!_=+,-./"']; + fragment INT: [0] | [0-9] [0-9]* ; -fragment EXP: [Ee] [+\-]? INT ; +fragment EXP: [Ee] [+\-]? INT ; +fragment ESC: '\\' (["\\/bfnrt] | UNICODE) ; +fragment UNICODE : 'u' HEX HEX HEX HEX ; +fragment HEX : [0-9a-fA-F] ; -WS: [ \t\n\r]+ -> channel(WHITESPACE) ; \ No newline at end of file +// NOTE: If WHITESPACE is changed from 1, please also change the following line below: +// WS: [ \t\n\r]+ -> channel(1) ; +// This is hardwired to 1 (instead of WHITESPACE) to avoid a compiler warning. +WS: [ \t\n\r]+ -> channel(1) ; \ No newline at end of file diff --git a/Source/Revit.IFC.Export/Utility/ParameterUtil.cs b/Source/Revit.IFC.Export/Utility/ParameterUtil.cs index 935e61dc..d6c2fc47 100644 --- a/Source/Revit.IFC.Export/Utility/ParameterUtil.cs +++ b/Source/Revit.IFC.Export/Utility/ParameterUtil.cs @@ -27,8 +27,44 @@ namespace Revit.IFC.Export.Utility /// /// Provides static methods for parameter related manipulations. /// - class ParameterUtil + public class ParameterUtil { + /// + /// The information needed to create an IFC property. + /// + public class PropertyDescription + { + /// + /// Create a property description with only a name. + /// + /// The name of the property. + public PropertyDescription(string name) + { + Name = name; + } + + /// + /// Create a property description with only a name. + /// + /// The name of the property. + /// The description of the property. + public PropertyDescription(string name, string description) + { + Name = name; + Description = description; + } + + /// + /// The required name. + /// + public string Name { get; set; } = null; + + /// + /// The optional description. + /// + public string Description { get; set; } = null; + }; + // Cache the parameters for the current Element. private static IDictionary> m_NonIFCParameters = new Dictionary>(); diff --git a/Source/Revit.IFC.Export/Utility/ProductWrapper.cs b/Source/Revit.IFC.Export/Utility/ProductWrapper.cs index 62068357..36819032 100644 --- a/Source/Revit.IFC.Export/Utility/ProductWrapper.cs +++ b/Source/Revit.IFC.Export/Utility/ProductWrapper.cs @@ -73,6 +73,13 @@ protected ProductWrapper(ExporterIFC exporterIFC) ExporterCacheManager.ElementToHandleCache.Register(element.Id, handle, exportType); ExporterCacheManager.HandleToElementCache.Register(handle, element.Id); + + if (SpatialElementExporter.IsZoneCompatible(exportType)) + { + IFCFile file = ExporterIFC.GetFile(); + SpatialElementExporter.CreateZoneInfos(file, element, handle); + SpatialElementExporter.CreateSpaceOccupantInfo(file, element, handle); + } } /// @@ -172,29 +179,6 @@ public bool IsEmpty() return ((CreatedHandles.Count == 0) && (InternalWrapper.Count == 0)); } - /// - /// Gets the first handle of a particular type, or null if none exists. - /// - /// The entity type. - /// The handle, or null. - public IFCAnyHandle GetElementOfType(IFCEntityType type) - { - foreach (IFCAnyHandle handle in CreatedHandles) - { - if (IFCAnyHandleUtil.IsSubTypeOf(handle, type)) - return handle; - } - - ICollection internalObjects = InternalWrapper.GetAllObjects(); - foreach (IFCAnyHandle handle in internalObjects) - { - if (IFCAnyHandleUtil.IsSubTypeOf(handle, type)) - return handle; - } - - return null; - } - /// /// Get all handles in the wrapper. /// @@ -211,8 +195,7 @@ public ISet GetAllObjects() // of disposal of entities, and in general a move to .NET only created entities. foreach (IFCAnyHandle internalObject in internalObjects) { - if (!IFCAnyHandleUtil.IsNullOrHasNoValue(internalObject)) - allObjects.Add(internalObject); + allObjects.AddIfNotNull(internalObject); } allObjects.UnionWith(CreatedHandles); diff --git a/Source/Revit.IFC.Export/Utility/PropertyInfoCache.cs b/Source/Revit.IFC.Export/Utility/PropertyInfoCache.cs index 9c1a7651..32c0e02a 100644 --- a/Source/Revit.IFC.Export/Utility/PropertyInfoCache.cs +++ b/Source/Revit.IFC.Export/Utility/PropertyInfoCache.cs @@ -174,174 +174,20 @@ public StringPropertyInfoCache IdentifierCache } } - /// - /// The DoublePropertyInfoCache object for Real parameter types. - /// - public DoublePropertyInfoCache RealCache - { - get - { - DoublePropertyInfoCache realPropertyInfoCache; - if (!DoubleCacheMap.TryGetValue(PropertyType.Real, out realPropertyInfoCache)) - { - realPropertyInfoCache = new DoublePropertyInfoCache(); - DoubleCacheMap[PropertyType.Real] = realPropertyInfoCache; - } - return realPropertyInfoCache; - } - } - - /// - /// The DoublePropertyInfoCache object for Numeric parameter types. - /// - public DoublePropertyInfoCache NumericCache - { - get - { - DoublePropertyInfoCache numericPropertyInfoCache; - if (!DoubleCacheMap.TryGetValue(PropertyType.Numeric, out numericPropertyInfoCache)) - { - numericPropertyInfoCache = new DoublePropertyInfoCache(); - DoubleCacheMap[PropertyType.Numeric] = numericPropertyInfoCache; - } - return numericPropertyInfoCache; - } - } - - /// - /// The DoublePropertyInfoCache object for LengthMeasure parameter types. - /// - public DoublePropertyInfoCache LengthMeasureCache - { - get - { - DoublePropertyInfoCache lengthMeasurePropertyInfoCache; - if (!DoubleCacheMap.TryGetValue(PropertyType.Length, out lengthMeasurePropertyInfoCache)) - { - lengthMeasurePropertyInfoCache = new DoublePropertyInfoCache(); - DoubleCacheMap[PropertyType.Length] = lengthMeasurePropertyInfoCache; - } - return lengthMeasurePropertyInfoCache; - } - } /// - /// The DoublePropertyInfoCache object for PlaneAngle parameter types. + /// Get DoublePropertyInfoCache object for the particular type /// - public DoublePropertyInfoCache PlaneAngleCache + public DoublePropertyInfoCache GetDoubleChache(PropertyType propertyType) { - get + DoublePropertyInfoCache doublePropertyInfoCache; + if (!DoubleCacheMap.TryGetValue(propertyType, out doublePropertyInfoCache)) { - DoublePropertyInfoCache planeAngleCache; - if (!DoubleCacheMap.TryGetValue(PropertyType.PlaneAngle, out planeAngleCache)) - { - planeAngleCache = new DoublePropertyInfoCache(); - DoubleCacheMap[PropertyType.PlaneAngle] = planeAngleCache; - } - return planeAngleCache; + doublePropertyInfoCache = new DoublePropertyInfoCache(); + DoubleCacheMap[propertyType] = doublePropertyInfoCache; } + return doublePropertyInfoCache; } - /// - /// The DoublePropertyInfoCache object for ElectricalCurrent parameter types. - /// - public DoublePropertyInfoCache ElectricCurrentCache - { - get - { - DoublePropertyInfoCache electricalCurrentCache; - if (!DoubleCacheMap.TryGetValue(PropertyType.ElectricCurrent, out electricalCurrentCache)) - { - electricalCurrentCache = new DoublePropertyInfoCache(); - DoubleCacheMap[PropertyType.ElectricCurrent] = electricalCurrentCache; - } - return electricalCurrentCache; - } - } - - /// - /// The DoublePropertyInfoCache object for ElectricalVoltage parameter types. - /// - public DoublePropertyInfoCache ElectricVoltageCache - { - get - { - DoublePropertyInfoCache electricalVoltageCache; - if (!DoubleCacheMap.TryGetValue(PropertyType.ElectricVoltage, out electricalVoltageCache)) - { - electricalVoltageCache = new DoublePropertyInfoCache(); - DoubleCacheMap[PropertyType.ElectricVoltage] = electricalVoltageCache; - } - return electricalVoltageCache; - } - } - - /// - /// The DoublePropertyInfoCache object for PositivePlaneAngle parameter types. - /// - public DoublePropertyInfoCache PositivePlaneAngleCache - { - get - { - DoublePropertyInfoCache planeAngleCache; - if (!DoubleCacheMap.TryGetValue(PropertyType.PlaneAngle, out planeAngleCache)) - { - planeAngleCache = new DoublePropertyInfoCache(); - DoubleCacheMap[PropertyType.PositivePlaneAngle] = planeAngleCache; - } - return planeAngleCache; - } - } - - /// - /// The DoublePropertyInfoCache object for ThermodynamicTemperature parameter types. - /// - public DoublePropertyInfoCache ThermodynamicTemperatureCache - { - get - { - DoublePropertyInfoCache thermodynamicTemperaturePropertyInfoCache; - if (!DoubleCacheMap.TryGetValue(PropertyType.ThermodynamicTemperature, out thermodynamicTemperaturePropertyInfoCache)) - { - thermodynamicTemperaturePropertyInfoCache = new DoublePropertyInfoCache(); - DoubleCacheMap[PropertyType.ThermodynamicTemperature] = thermodynamicTemperaturePropertyInfoCache; - } - return thermodynamicTemperaturePropertyInfoCache; - } - } - - /// - /// The DoublePropertyInfoCache object for ThermalTransmittance parameter types. - /// - public DoublePropertyInfoCache ThermalTransmittanceCache - { - get - { - DoublePropertyInfoCache thermalTransmittancePropertyInfoCache; - if (!DoubleCacheMap.TryGetValue(PropertyType.ThermalTransmittance, out thermalTransmittancePropertyInfoCache)) - { - thermalTransmittancePropertyInfoCache = new DoublePropertyInfoCache(); - DoubleCacheMap[PropertyType.ThermalTransmittance] = thermalTransmittancePropertyInfoCache; - } - return thermalTransmittancePropertyInfoCache; - } - } - - /// - /// The DoublePropertyInfoCache object for Power parameter types. - /// - public DoublePropertyInfoCache PowerCache - { - get - { - DoublePropertyInfoCache powerPropertyInfoCache; - if (!DoubleCacheMap.TryGetValue(PropertyType.Power, out powerPropertyInfoCache)) - { - powerPropertyInfoCache = new DoublePropertyInfoCache(); - DoubleCacheMap[PropertyType.Power] = powerPropertyInfoCache; - } - return powerPropertyInfoCache; - } - } } } diff --git a/Source/Revit.IFC.Export/Utility/PropertyMap.cs b/Source/Revit.IFC.Export/Utility/PropertyMap.cs index 760c7188..82b45d88 100644 --- a/Source/Revit.IFC.Export/Utility/PropertyMap.cs +++ b/Source/Revit.IFC.Export/Utility/PropertyMap.cs @@ -19,73 +19,248 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; using System.IO; -using System.Text.RegularExpressions; -using GeometryGym.Ifc; +using Autodesk.Revit.DB; +using Revit.IFC.Export.Exporter.PropertySet; namespace Revit.IFC.Export.Utility { /// - /// Type or Instance enum + /// Represents the Revit parameter to get from element. /// - public enum TypeOrInstance + class UserDefinedPropertyRevitParameter { - Type, - Instance - } + /// + /// Gets Revit . + /// + public BuiltInParameter BuiltInParameter { get; private set; } = BuiltInParameter.INVALID; - /// - /// PropertSet definition struct - /// - public struct PropertySetDef - { - public string propertySetName; - public string propertySetDescription; - public IList propertyDefs; - public TypeOrInstance applicableTo; - public IList applicableElements; + /// + /// Gets custom Revit paramater name. + /// + public string RevitParameter { get; private set; } = null; + + /// + /// Gets a value indicating whether the Revit built-in parameter specified. + /// + public bool IsBuiltInParameterDefined { get; private set; } = false; + + /// + /// Creates a new revit parameter representation instance for the given raw definition from the config. + /// + /// Data to parse. + /// A new instance of . + public static UserDefinedPropertyRevitParameter Create(string rawParameter) + { + if (string.IsNullOrWhiteSpace(rawParameter)) + return null; + + UserDefinedPropertyRevitParameter parameter = new UserDefinedPropertyRevitParameter(); + const string prefix = "BuiltInParameter."; + if (rawParameter.StartsWith(prefix, StringComparison.InvariantCultureIgnoreCase)) + { + parameter.IsBuiltInParameterDefined = true; + string builtinParameterName = rawParameter.Substring(prefix.Length); + if (Enum.TryParse(builtinParameterName, out BuiltInParameter builtInParameter) && builtInParameter != BuiltInParameter.INVALID) + { + parameter.BuiltInParameter = builtInParameter; + } + } + else + { + parameter.RevitParameter = rawParameter; + } + + return parameter; + } } /// - /// Property + /// Represents a single property definiton from the config. /// - public class PropertyDef + class UserDefinedProperty { - public string PropertyName; - public string PropertyDataType; - public List ParameterDefinitions = new List(); - //public GeometryGym.Ifc.IfcValue DefaultValue = null; - public PropertyDef(string propertyName) + /// + /// Gets or sets a property name. + /// + public string Name { get; set; } + + /// + /// Gets a list of defined Revit parameters. + /// + public List RevitParameters { get; private set; } = new List(); + + /// + /// Gets a property value type. By default . + /// + public PropertyValueType IfcPropertyValueType { get; private set; } = PropertyValueType.SingleValue; + + /// + /// Gets a list of property types. + /// + public List IfcPropertyTypes { get; private set; } = new List(); + + /// + /// Parses and sets and by given . + /// + /// Property type data to parse. + public void ParseIfcPropertyTypes(string rawIfcPropertyTypes) { - PropertyName = propertyName; - ParameterDefinitions.Add(new PropertyParameterDefinition(propertyName)); + if (string.IsNullOrWhiteSpace(rawIfcPropertyTypes)) + return; + + // format: .//... + IfcPropertyTypes.Clear(); + string dataTypePartToParse = string.Empty; + string[] split = rawIfcPropertyTypes.Split('.') ?? new string[] {}; + if (split.Length == 1) + { + IfcPropertyValueType = PropertyValueType.SingleValue; + dataTypePartToParse = split[0]; + } + else if (split.Length >= 2) + { + const string prefix = "Property"; + bool withPrefix = split[0].StartsWith(prefix, StringComparison.InvariantCultureIgnoreCase); + string rawValueType = withPrefix ? split[0].Substring(prefix.Length) : split[0]; + if (!Enum.TryParse(rawValueType, true, out PropertyValueType propertyValueType)) + { + propertyValueType = PropertyValueType.SingleValue; + } + + IfcPropertyValueType = propertyValueType; + dataTypePartToParse = split[1]; + } + + string[] rawPropertyTypes = dataTypePartToParse.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); + foreach(string rawPropertyType in rawPropertyTypes) + { + const string prefix = "Ifc"; + bool withPrefix = rawPropertyType.StartsWith(prefix, StringComparison.InvariantCultureIgnoreCase); + IfcPropertyTypes.Add(withPrefix ? rawPropertyType.Substring(prefix.Length) : rawPropertyType); + } } - public PropertyDef(string propertyName, PropertyParameterDefinition definition) + + /// + /// Parses a list of revit parameters by given data from config. + /// + /// Data to parse. + public void ParseRevitParameters(string rawParameters) { - PropertyName = propertyName; - ParameterDefinitions.Add(definition); + if (string.IsNullOrWhiteSpace(rawParameters)) + return; + + RevitParameters.Clear(); + UserDefinedPropertyRevitParameter parameter = UserDefinedPropertyRevitParameter.Create(rawParameters); + if (parameter != null) + RevitParameters.Add(parameter); } - public PropertyDef(string propertyName, IEnumerable definitions) + + /// + /// Gets Revit parameters mapped into list of T type. + /// + /// The type of list elements. + /// Function to initialize T. + /// A list of Revit parameters mapped into list of T type. + public List GetEntryMap(Func mapper) where T : EntryMap, new() { - PropertyName = propertyName; - ParameterDefinitions.AddRange(definitions); + List entryMap = new List(); + foreach (UserDefinedPropertyRevitParameter parameter in RevitParameters) + { + if (parameter.BuiltInParameter != BuiltInParameter.INVALID) + { + entryMap.Add(mapper(Name, parameter.BuiltInParameter)); + } + else if (!parameter.IsBuiltInParameterDefined) + { + entryMap.Add(mapper(parameter.RevitParameter, BuiltInParameter.INVALID)); + } + else + { + // report as error in log when we create log file. + } + } + + return entryMap; } - } - public class PropertyParameterDefinition - { - public string RevitParameterName = ""; - public Autodesk.Revit.DB.BuiltInParameter RevitBuiltInParameter = Autodesk.Revit.DB.BuiltInParameter.INVALID; - public PropertyParameterDefinition(string revitParameterName) + + /// + /// Returns the first element of converted to , + /// or a if contains no elements. + /// + /// The enumeration type to which to convert value. + /// + /// Value to return if the index is out of range, if is empty or + /// first element value is not represented in the . + /// + /// + /// if source is empty; otherwise, the first element in + /// converted to + /// + public TEnum FirstIfcPropertyTypeOrDefault(TEnum defaultValue) where TEnum : struct { - RevitParameterName = revitParameterName; + if ((IfcPropertyTypes?.Count ?? 0) == 0) + return defaultValue; + + if(Enum.TryParse(IfcPropertyTypes[0], true, out TEnum t)) + return t; + + return defaultValue; } - public PropertyParameterDefinition(Autodesk.Revit.DB.BuiltInParameter builtInParameter) + + /// + /// Returns the type at a specified index in converted to + /// or a default value if the index is out of range, if is empty, if value at a specified + /// index is not represented in the . + /// + /// The enumeration type to which to convert value. + /// The zero-based index of the element to retrieve. + /// + /// Value to return if the index is out of range, if is empty, if value at a specified + /// index is not represented in the . + /// + /// + /// if the index is outside the bounds of the source sequence or is empty; + /// otherwise,the element at the specified position in the source sequence. + /// + public TEnum GetIfcPropertyAtOrDefault(int index, TEnum defaultValue) where TEnum : struct { - RevitBuiltInParameter = builtInParameter; + if ((IfcPropertyTypes?.Count ?? 0) == 0 || IfcPropertyTypes.Count >= index || index < 0) + return defaultValue; + + if (Enum.TryParse(IfcPropertyTypes[index], true, out TEnum t)) + return t; + + return defaultValue; } } + + /// + /// Represents a property set from the config. + /// + class UserDefinedPropertySet + { + /// + /// Gets a property set name. + /// + public string Name { get; set; } + + /// + /// Gets a type of elements group for which the property set is defined. + /// + public string Type { get; set; } + + /// + /// Gets a list of IFC entites for which property set is defined. + /// + public string[] IfcEntities { get; set; } + + /// + /// Gets a list of properties in the property set. + /// + public IList Properties { get; set; } = new List(); + } + class PropertyMap { /// @@ -133,7 +308,7 @@ private static void ParseLine(Dictionary, string> paramete { // add the line string[] split = line.Split(new char[] { '\t' }, StringSplitOptions.RemoveEmptyEntries); - if (split.Count() == 3) + if (split.Length == 3) parameterMap.Add(Tuple.Create(split[0], split[1]), split[2]); } } @@ -141,7 +316,7 @@ private static void ParseLine(Dictionary, string> paramete /// /// Load user-defined Property set /// Format: - /// PropertSet: I[nstance]/T[ype] + /// PropertySet: I[nstance]/T[ype] /// Property_name Data_type Revit_Parameter /// ... /// Datatype supported: Text, Integer, Real, Boolean @@ -149,9 +324,9 @@ private static void ParseLine(Dictionary, string> paramete /// #! UserDefinedPset /// /// List of property set definitions - public static IEnumerable LoadUserDefinedPset() + public static IEnumerable LoadUserDefinedPset() { - List userDefinedPsets = new List(); + List userDefinedPropertySets = new List(); try { @@ -162,105 +337,48 @@ public static IEnumerable LoadUserDefinedPset() filename = GetUserDefPsetFilename(); } if (!File.Exists(filename)) - return userDefinedPsets; + return userDefinedPropertySets; - string extension = Path.GetExtension(filename); - if (string.Compare(extension, ".ifcxml", true) == 0 || string.Compare(extension, ".ifcjson", true) == 0 || string.Compare(extension, ".ifc", true) == 0) + // Format: PropertSet: I[nstance]/T[ype] + // Property_name Data_type Revit_Parameter + // ** For now it only works for simple property with single value (datatype supported: Text, Integer, Real and Boolean) + using (StreamReader sr = new StreamReader(filename)) { - DatabaseIfc db = new DatabaseIfc(filename); - IfcContext context = db.Context; - if (context == null) - return userDefinedPsets; - foreach (IfcRelDeclares relDeclares in context.Declares) - { - userDefinedPsets.AddRange(relDeclares.RelatedDefinitions.OfType()); - } - } - else - { - using (StreamReader sr = new StreamReader(filename)) + string line; + + // current property set + UserDefinedPropertySet userDefinedPropertySet = null; + while ((line = sr.ReadLine()) != null) { - string line; + line = line.TrimStart(' ', '\t'); - DatabaseIfc db = new DatabaseIfc(ReleaseVersion.IFC4A2); - IfcPropertySetTemplate userDefinedPset = null; - while ((line = sr.ReadLine()) != null) + if (string.IsNullOrEmpty(line) || line[0] == '#') + continue; + + string[] split = line.Split(new char[] { '\t' }, StringSplitOptions.RemoveEmptyEntries); + if (split.Length >=4 && string.Compare(split[0], "PropertySet:", true) == 0) // Any entry with less than 3 parameters is malformed. { - line.TrimStart(' ', '\t'); + userDefinedPropertySet = new UserDefinedPropertySet() + { + Name = split[1], + Type = split[2], + IfcEntities = split[3].Split(new char[] { ',', ';', ' ' }, StringSplitOptions.RemoveEmptyEntries) + }; - if (String.IsNullOrEmpty(line)) continue; - if (line[0] != '#') + userDefinedPropertySets.Add(userDefinedPropertySet); + } + else if (split.Length >= 2 && userDefinedPropertySet != null) // Skip property definitions outside of property set block. + { + UserDefinedProperty userDefinedProperty = new UserDefinedProperty(); + userDefinedProperty.Name = split[0]; + userDefinedProperty.ParseIfcPropertyTypes(split[1]); + + if (split.Length >= 3) { - // Format: PropertSet: I[nstance]/T[ype] - // Property_name Data_type Revit_Parameter - // ** For now it only works for simple property with single value (datatype supported: Text, Integer, Real and Boolean) - - string[] split = line.Split(new char[] { '\t' }, StringSplitOptions.RemoveEmptyEntries); - if (string.Compare(split[0], "PropertySet:", true) == 0) - { - userDefinedPset = new IfcPropertySetTemplate(db, split.Length > 2 ? split[1] : "Unknown"); - if (split.Count() >= 4) // Any entry with less than 3 par is malformed - { - switch (split[2][0]) - { - case 'T': - userDefinedPset.TemplateType = IfcPropertySetTemplateTypeEnum.PSET_TYPEDRIVENONLY; - break; - case 'I': - userDefinedPset.TemplateType = IfcPropertySetTemplateTypeEnum.PSET_OCCURRENCEDRIVEN; - break; - default: - userDefinedPset.TemplateType = IfcPropertySetTemplateTypeEnum.PSET_OCCURRENCEDRIVEN; - break; - } - userDefinedPset.ApplicableEntity = string.Join(",", split[3].Split(new char[] { ',', ';', ' ' }, StringSplitOptions.RemoveEmptyEntries)); - userDefinedPsets.Add(userDefinedPset); - } - } - else - { - if (split.Count() >= 2) - { - string propertyTemplateName = split[0]; - IfcSimplePropertyTemplate propertyDefUnit = userDefinedPset[propertyTemplateName] as IfcSimplePropertyTemplate; - if(propertyDefUnit == null) - userDefinedPset.AddPropertyTemplate(propertyDefUnit = new IfcSimplePropertyTemplate(db, split[0])); - if (split.Count() >= 3 && !string.IsNullOrEmpty(split[2])) - { - new IfcRelAssociatesClassification(new IfcClassificationReference(db) { Identification = split[2] }, propertyDefUnit); - } - if (!string.IsNullOrEmpty(split[1])) - { - string[] propertyTypeVals = split[1].Split(new char[] {'.'}, StringSplitOptions.RemoveEmptyEntries); - if (propertyTypeVals.Count() > 1) - { - switch (propertyTypeVals[0]) - { - case "PropertyListValue": - propertyDefUnit.TemplateType = IfcSimplePropertyTemplateTypeEnum.P_LISTVALUE; - break; - case "PropertyBoundedValue": - propertyDefUnit.TemplateType = IfcSimplePropertyTemplateTypeEnum.P_BOUNDEDVALUE; - break; - case "PropertyTableValue": - propertyDefUnit.TemplateType = IfcSimplePropertyTemplateTypeEnum.P_TABLEVALUE; - break; - default: - propertyDefUnit.TemplateType = IfcSimplePropertyTemplateTypeEnum.P_SINGLEVALUE; - break; - } - - string[] measureTypes = propertyTypeVals[1].Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); - propertyDefUnit.PrimaryMeasureType = "Ifc" + measureTypes[0]; - if (measureTypes.Count() == 2) - propertyDefUnit.SecondaryMeasureType = "Ifc" + measureTypes[1]; - } - else - propertyDefUnit.PrimaryMeasureType = "Ifc" + propertyTypeVals[0]; - } - } - } + userDefinedProperty.ParseRevitParameters(split[2]); } + + userDefinedPropertySet.Properties.Add(userDefinedProperty); } } } @@ -271,7 +389,7 @@ public static IEnumerable LoadUserDefinedPset() Console.WriteLine(e.Message); } - return userDefinedPsets; + return userDefinedPropertySets; } /// diff --git a/Source/Revit.IFC.Export/Utility/RepresentationUtil.cs b/Source/Revit.IFC.Export/Utility/RepresentationUtil.cs index 17589f82..270a38be 100644 --- a/Source/Revit.IFC.Export/Utility/RepresentationUtil.cs +++ b/Source/Revit.IFC.Export/Utility/RepresentationUtil.cs @@ -526,12 +526,14 @@ public static IFCAnyHandle CreateBoundingBoxRep(ExporterIFC exporterIFC, IFCAnyH /// The category id. /// The context for which the different subtypes of representation are valid. /// Set of geometric representation items that are defined for this representation. + /// If true, creates a GeometricSet instead of an Annotation2D. /// The handle. public static IFCAnyHandle CreateAnnotationSetRep(ExporterIFC exporterIFC, Element element, ElementId categoryId, - IFCAnyHandle contextOfItems, HashSet bodyItems) + IFCAnyHandle contextOfItems, HashSet bodyItems, bool is3D) { string identifierOpt = "Annotation"; - string repTypeOpt = ShapeRepresentationType.Annotation2D.ToString(); // this is by IFC2x3 convention + string repTypeOpt = is3D ? ShapeRepresentationType.GeometricSet.ToString() : + ShapeRepresentationType.Annotation2D.ToString(); IFCAnyHandle bodyRepresentation = CreateShapeRepresentation(exporterIFC, element, categoryId, contextOfItems, identifierOpt, repTypeOpt, bodyItems); @@ -640,6 +642,8 @@ public static IFCAnyHandle CreateBoundingBoxRep(ExporterIFC exporterIFC, IFCAnyH if (boundingBoxRep != null) bodyReps.Add(boundingBoxRep); + // NOTE: This can create an invalid IfcProductDefinitionShape with no representations. The expectation is + // that these will be created later, but at the moment that is not guaranteed. return IFCInstanceExporter.CreateProductDefinitionShape(exporterIFC.GetFile(), null, null, bodyReps); } diff --git a/Source/Revit.IFC.Export/Utility/SimpleSweptSolidAnalyzer.cs b/Source/Revit.IFC.Export/Utility/SimpleSweptSolidAnalyzer.cs index f4e2145a..67f7e11f 100644 --- a/Source/Revit.IFC.Export/Utility/SimpleSweptSolidAnalyzer.cs +++ b/Source/Revit.IFC.Export/Utility/SimpleSweptSolidAnalyzer.cs @@ -20,7 +20,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; using Autodesk.Revit.DB; using Revit.IFC.Common.Utility; @@ -35,45 +34,20 @@ namespace Revit.IFC.Export.Utility /// class SimpleSweptSolidAnalyzer { - PlanarFace m_ProfileFace; - - Curve m_PathCurve; - - XYZ m_ReferencePlaneNormal; - - List m_UnalignedFaces; - /// /// The face that represents the profile of the swept solid. /// - public PlanarFace ProfileFace - { - get { return m_ProfileFace; } - } + public PlanarFace ProfileFace { get; private set; } = null; /// /// The edge that represents the path of the swept solid. /// - public Curve PathCurve - { - get { return m_PathCurve; } - } - - /// - /// The normal of the reference plane that the path lies on. - /// - public XYZ ReferencePlaneNormal - { - get { return m_ReferencePlaneNormal; } - } + public Curve PathCurve { get; private set; } = null; /// /// The unaligned faces, maybe openings or recesses. /// - public List UnalignedFaces - { - get { return m_UnalignedFaces; } - } + public List UnalignedFaces { get; } = new List(); /// /// Creates a SimpleSweptSolidAnalyzer and computes the swept solid. @@ -110,7 +84,8 @@ public static SimpleSweptSolidAnalyzer Create(ICollection faces, XYZ norma IList> potentialSweptAreaFaces = new List>(); Curve directrix = potentialPathGeom as Curve; - if (potentialPathGeom == null) + // In some cases potentialPathGeom comes as PolyLine + if (directrix == null) return Create(faces, normal); XYZ directrixStartPt = directrix.GetEndPoint(0); @@ -191,14 +166,158 @@ public static SimpleSweptSolidAnalyzer Create(ICollection faces, XYZ norma if (sweptEndStartFace != null) { simpleSweptSolidAnalyzer = new SimpleSweptSolidAnalyzer(); - simpleSweptSolidAnalyzer.m_ProfileFace = sweptEndStartFace; - simpleSweptSolidAnalyzer.m_PathCurve = directrix; - simpleSweptSolidAnalyzer.m_ReferencePlaneNormal = normal; + simpleSweptSolidAnalyzer.ProfileFace = sweptEndStartFace; + simpleSweptSolidAnalyzer.PathCurve = directrix; } return simpleSweptSolidAnalyzer; } + private static Curve GetPathCurve(PlanarFace profileFace1, PlanarFace profileFace2, + IList cylindricalFaces, EdgeArray edgeArray) + { + // Get an arbitrary curve from any of the cylindrical faces that isn't shared with either of + // the provided planar faces. + // Assumptions of this routine: 2 planar faces, all cylindrical faces have 4 edges. + foreach (Edge edge in edgeArray) + { + Face edgeFace0 = edge.GetFace(0); + if (edgeFace0 == profileFace1 || edgeFace0 == profileFace2) + { + continue; + } + + Face edgeFace1 = edge.GetFace(1); + if (edgeFace1 == profileFace1 || edgeFace1 == profileFace2) + { + continue; + } + + Curve curve = edge.AsCurveFollowingFace(cylindricalFaces[0]); + if (curve is Line) + { + // This is a cylinder. + return null; + } + + return curve; + } + + return null; + } + + /// + /// Creates a SimpleSweptSolidAnalyzer and computes the swept solid. + /// + /// The faces of a solid. + /// The analyzer. + /// This is very specialized for a solid made of planes and cylinders. + public static SimpleSweptSolidAnalyzer CreateFromSimpleCylindricalSurfaces(ICollection faces) + { + int numFaces = faces?.Count ?? 0; + if (numFaces < 3) + { + // Invalid faces. + return null; + } + + // Only acceptable cases: planarFaces + at least 1 cylindricalFace, and no other face types. + // All faces have either 4 edges, except for the two end planar faces that have numFaces-2 edges. + IList endPlanarFaces = new List(); + IList cylindricalFaces = new List(); + EdgeArray edgeArray = null; + + int numEndPlanarFaces = 0; + + foreach (Face face in faces) + { + EdgeArrayArray edgeArrayArray = face.EdgeLoops; + if ((edgeArrayArray?.Size ?? 0) != 1) + { + return null; + } + + EdgeArray currEdgeArray = edgeArrayArray.get_Item(0); + int currEdgeArraySize = currEdgeArray.Size; + + if (face is CylindricalFace) + { + if (currEdgeArraySize != 4) + { + return null; + } + if (edgeArray == null) + { + edgeArray = currEdgeArray; + } + + cylindricalFaces.Add(face as CylindricalFace); + continue; + } + else if (face is PlanarFace) + { + PlanarFace planarFace = face as PlanarFace; + if (currEdgeArraySize == 4) + { + continue; + } + + if (numEndPlanarFaces == 2 || currEdgeArraySize != numFaces - 2) + { + return null; + } + + numEndPlanarFaces++; + endPlanarFaces.Add(planarFace); + } + else + { + return null; + } + } + + if (numEndPlanarFaces < 2 || cylindricalFaces.Count == 0) + { + return null; + } + + Curve pathCurve = GetPathCurve(endPlanarFaces[0], endPlanarFaces[1], cylindricalFaces, edgeArray); + if (pathCurve == null || !pathCurve.IsBound) + { + return null; + } + + XYZ firstPlaneNormal = endPlanarFaces[0].FaceNormal; + XYZ firstPlaneOrigin = endPlanarFaces[0].Origin; + if (!MathUtil.IsAlmostZero((pathCurve.GetEndPoint(0) - firstPlaneOrigin).DotProduct(firstPlaneNormal))) + { + pathCurve = pathCurve.CreateReversed(); + // Sanity check. + if (!MathUtil.IsAlmostZero((pathCurve.GetEndPoint(0) - firstPlaneOrigin).DotProduct(firstPlaneNormal))) + { + return null; + } + } + + XYZ startPathCurveNormal = pathCurve.ComputeDerivatives(0, true).BasisX.Normalize(); + XYZ endPathCurveNormal = pathCurve.ComputeDerivatives(1, true).BasisX.Normalize(); + + XYZ secondPlaneNormal = endPlanarFaces[1].FaceNormal; + + if (firstPlaneNormal.IsAlmostEqualTo(-startPathCurveNormal) && + secondPlaneNormal.IsAlmostEqualTo(endPathCurveNormal)) + { + SimpleSweptSolidAnalyzer simpleSweptSolidAnalyzer = new SimpleSweptSolidAnalyzer(); + + simpleSweptSolidAnalyzer.ProfileFace = endPlanarFaces[0]; + simpleSweptSolidAnalyzer.PathCurve = pathCurve; + + return simpleSweptSolidAnalyzer; + } + + return null; + } + /// /// Creates a SimpleSweptSolidAnalyzer and computes the swept solid. /// @@ -208,7 +327,14 @@ public static SimpleSweptSolidAnalyzer Create(ICollection faces, XYZ norma /// This is a simple analyzer, and is not intended to be general - it works in some simple, real-world cases. public static SimpleSweptSolidAnalyzer Create(ICollection faces, XYZ normal) { - if (faces == null || faces.Count < 3) + SimpleSweptSolidAnalyzer simpleSweptSolidAnalyzer = CreateFromSimpleCylindricalSurfaces(faces); + if (simpleSweptSolidAnalyzer != null) + { + return simpleSweptSolidAnalyzer; + } + + int numFaces = faces?.Count ?? 0; + if (numFaces < 3) { // Invalid faces. return null; @@ -324,9 +450,11 @@ public static SimpleSweptSolidAnalyzer Create(ICollection faces, XYZ norma Dictionary> sideFacesWithEdgesDic = new Dictionary>(); foreach (Face sideFace in sideFacesWithCandidateEdges.Keys) { - sideFacesWithEdgesDic[sideFace] = new List(); - sideFacesWithEdgesDic[sideFace].Add(sideFacesWithCandidateEdges[sideFace]); - sideFacesWithEdgesDic[sideFace].Add(sideFacesWithTheOtherCandidateEdges[sideFace]); + sideFacesWithEdgesDic[sideFace] = new List() + { + sideFacesWithCandidateEdges[sideFace], + sideFacesWithTheOtherCandidateEdges[sideFace] + }; } if (!AreFacesSimpleCongruent(sideFacesWithEdgesDic)) @@ -364,8 +492,6 @@ public static SimpleSweptSolidAnalyzer Create(ICollection faces, XYZ norma break; } while (ii < potentialSweepEndFaces.Count); - SimpleSweptSolidAnalyzer simpleSweptSolidAnalyzer = null; - if (foundCandidateFace) { simpleSweptSolidAnalyzer = new SimpleSweptSolidAnalyzer(); @@ -373,9 +499,7 @@ public static SimpleSweptSolidAnalyzer Create(ICollection faces, XYZ norma XYZ endPoint0 = pathCurve.GetEndPoint(0); bool foundProfileFace = false; - List profileFaces = new List(); - profileFaces.Add(candidateProfileFace); - profileFaces.Add(candidateProfileFace2); + List profileFaces = new List() { candidateProfileFace, candidateProfileFace2 }; foreach (PlanarFace profileFace in profileFaces) { @@ -388,7 +512,7 @@ public static SimpleSweptSolidAnalyzer Create(ICollection faces, XYZ norma XYZ intersectPoint = intersectionResult.XYZPoint; if (intersectPoint.IsAlmostEqualTo(endPoint0)) { - simpleSweptSolidAnalyzer.m_ProfileFace = profileFace; + simpleSweptSolidAnalyzer.ProfileFace = profileFace; foundProfileFace = true; break; } @@ -408,19 +532,15 @@ public static SimpleSweptSolidAnalyzer Create(ICollection faces, XYZ norma // TODO: consider one profile face has an opening extrusion inside while the other does not List alignedFaces = FindAlignedFaces(profileFaces.ToList()); - List unalignedFaces = new List(); foreach (Face face in faces) { if (profileFaces.Contains(face) || alignedFaces.Contains(face)) continue; - unalignedFaces.Add(face); + simpleSweptSolidAnalyzer.UnalignedFaces.Add(face); } - simpleSweptSolidAnalyzer.m_UnalignedFaces = unalignedFaces; - - simpleSweptSolidAnalyzer.m_PathCurve = pathCurve; - simpleSweptSolidAnalyzer.m_ReferencePlaneNormal = normal; + simpleSweptSolidAnalyzer.PathCurve = pathCurve; } return simpleSweptSolidAnalyzer; diff --git a/Source/Revit.IFC.Export/Utility/TriangleMergeUtil.cs b/Source/Revit.IFC.Export/Utility/TriangleMergeUtil.cs index fe01630b..968abbad 100644 --- a/Source/Revit.IFC.Export/Utility/TriangleMergeUtil.cs +++ b/Source/Revit.IFC.Export/Utility/TriangleMergeUtil.cs @@ -52,7 +52,7 @@ class IndexFace /// Constructor taking a list of vertex indices (face without hole) /// /// the list of vertex indices (face without hole) - public IndexFace(IList vertxIndices, ref IDictionary meshVertices) + public IndexFace(IList vertxIndices, IDictionary meshVertices) { IndexOuterBoundary = vertxIndices; SetupEdges(IndexOuterBoundary, 0); @@ -69,7 +69,7 @@ public IndexFace(IList vertxIndices, ref IDictionary meshVertices /// Constructor taking in List of List of vertices. The first list will be the outer boundary and the rest are the inner boundaries /// /// List of List of vertices. The first list will be the outer boundary and the rest are the inner boundaries - public IndexFace(IList> vertxIndices, ref IDictionary meshVertices) + public IndexFace(IList> vertxIndices, IDictionary meshVertices) { int vertexCount = vertxIndices?.Count ?? 0; if (vertexCount == 0) @@ -220,7 +220,7 @@ public IndexSegment(int startIndex, int endIndex) /// /// Extent size (length) of the line segment /// - public double Extent(ref IDictionary meshVertices) + public double Extent(IDictionary meshVertices) { return meshVertices[StartPindex].DistanceTo(meshVertices[EndPIndex]); } @@ -305,22 +305,23 @@ public int GetHashCode(XYZ obj) /// public class TriangleMergeUtil { - protected TriangulatedShellComponent m_Geom = null; - protected Mesh m_MeshGeom = null; + protected TriangulatedShellComponent TriangulatedShell { get; set; } = null; + protected Mesh MeshGeom { get; set; } = null; // A Dictionary is created for the mesh vertices due to performance issue for very large mesh if the vertex is accessed via its index - protected IDictionary m_MeshVertices = new Dictionary(); + protected IDictionary MeshVertices { get; set; } = new Dictionary(); - HashSet m_MergedFaceSet = new HashSet(); + HashSet MergedFaceSet { get; set; } = new HashSet(); + List MergedFaceIndices { get; set; } = new List(); - IDictionary m_FacesCollDict = new Dictionary(); - int faceIdxOffset = 0; + IDictionary FacesCollDict { get; set; } = new Dictionary(); + int FaceIdxOffset { get; set; } = 0; // These two must be hand in hand public const int DecimalPrecision = 6; public const double Tolerance = 1e-6; - public bool IsMesh { get { return (m_MeshGeom != null && m_Geom == null); } } + public bool IsMesh { get { return (MeshGeom != null && TriangulatedShell == null); } } /// /// Get the total number of triangles from the Mesh or the TriangulatedShellComponent object. @@ -328,10 +329,10 @@ public class TriangleMergeUtil /// The total number of triangles. public int GetTriangleCount() { - return (IsMesh) ? m_MeshGeom.NumTriangles : m_Geom.TriangleCount; + return (IsMesh) ? MeshGeom.NumTriangles : TriangulatedShell.TriangleCount; } - public List GetVertices() { return m_MeshVertices.Values.ToList(); } + public List GetVertices() { return MeshVertices.Values.ToList(); } /// /// Function called before and after triangle merging. @@ -342,30 +343,29 @@ private int CalculateEulerCharacteristic() { int noVertices = 0; int noHoles = 0; // Stays zero if mesh is triangular - int noFaces; + int noFaces = MergedFaceSet.Count; HashSet edges = new HashSet(new SegmentComparer(true/*compareBothDirections*/)); - if (m_MergedFaceSet.Count != 0) + if (noFaces != 0) { // Merging already occurred, calculate new Euler characteristic - noFaces = m_MergedFaceSet.Count; - foreach (int mergedFace in m_MergedFaceSet) + foreach (int mergedFace in MergedFaceSet) { - m_FacesCollDict[mergedFace].OuterAndInnerBoundaries.ToList().ForEach(vp => edges.Add(vp.Value)); - if (m_FacesCollDict[mergedFace].IndexedInnerBoundaries != null) - noHoles += m_FacesCollDict[mergedFace].IndexedInnerBoundaries.Count; + FacesCollDict[mergedFace].OuterAndInnerBoundaries.ToList().ForEach(vp => edges.Add(vp.Value)); + if (FacesCollDict[mergedFace].IndexedInnerBoundaries != null) + noHoles += FacesCollDict[mergedFace].IndexedInnerBoundaries.Count; } - noVertices = m_MeshVertices.Count; // m_MeshVertices doesn't contain isolated vertices + noVertices = MeshVertices.Count; // m_MeshVertices doesn't contain isolated vertices } else { if (IsMesh) { - noVertices = m_MeshGeom.Vertices.Count; - noFaces = m_MeshGeom.NumTriangles; + noVertices = MeshGeom.Vertices.Count; + noFaces = MeshGeom.NumTriangles; for (int faceIdx = 0; faceIdx < noFaces; faceIdx++) { - MeshTriangle tri = m_MeshGeom.get_Triangle(faceIdx); + MeshTriangle tri = MeshGeom.get_Triangle(faceIdx); edges.Add(new IndexSegment((int)tri.get_Index(0), (int)tri.get_Index(1))); edges.Add(new IndexSegment((int)tri.get_Index(1), (int)tri.get_Index(2))); edges.Add(new IndexSegment((int)tri.get_Index(2), (int)tri.get_Index(0))); @@ -373,11 +373,11 @@ private int CalculateEulerCharacteristic() } else { - noVertices = m_Geom.VertexCount; - noFaces = m_Geom.TriangleCount; + noVertices = TriangulatedShell.VertexCount; + noFaces = TriangulatedShell.TriangleCount; for (int faceIdx = 0; faceIdx < noFaces; faceIdx++) { - TriangleInShellComponent tri = m_Geom.GetTriangle(faceIdx); + TriangleInShellComponent tri = TriangulatedShell.GetTriangle(faceIdx); edges.Add(new IndexSegment(tri.VertexIndex0, tri.VertexIndex1)); edges.Add(new IndexSegment(tri.VertexIndex1, tri.VertexIndex2)); edges.Add(new IndexSegment(tri.VertexIndex2, tri.VertexIndex0)); @@ -395,8 +395,8 @@ private int CalculateEulerCharacteristic() /// public TriangleMergeUtil(TriangulatedShellComponent triangulatedBody) { - m_Geom = triangulatedBody; - m_MeshGeom = null; + TriangulatedShell = triangulatedBody; + MeshGeom = null; Reset(); } @@ -407,8 +407,8 @@ public TriangleMergeUtil(TriangulatedShellComponent triangulatedBody) /// the Mesh public TriangleMergeUtil(Mesh triangulatedMesh) { - m_Geom = null; - m_MeshGeom = triangulatedMesh; + TriangulatedShell = null; + MeshGeom = triangulatedMesh; Reset(); } @@ -417,19 +417,21 @@ public TriangleMergeUtil(Mesh triangulatedMesh) /// public void Reset() { - m_MergedFaceSet.Clear(); - m_FacesCollDict.Clear(); - m_MeshVertices.Clear(); - + MergedFaceSet.Clear(); + MergedFaceIndices.Clear(); + FacesCollDict.Clear(); + MeshVertices.Clear(); + FaceIdxOffset = 0; + IList vertices = null; - if (m_Geom != null) - vertices = m_Geom.GetVertices(); - else if (m_MeshGeom != null) - vertices = m_MeshGeom.Vertices; + if (TriangulatedShell != null) + vertices = TriangulatedShell.GetVertices(); + else if (MeshGeom != null) + vertices = MeshGeom.Vertices; if (vertices != null) for (int idx = 0; idx < vertices.Count; ++idx) - m_MeshVertices.Add(idx, vertices[idx]); + MeshVertices.Add(idx, vertices[idx]); } /// @@ -437,7 +439,7 @@ public void Reset() /// public int NoOfFaces { - get { return m_MergedFaceSet.Count; } + get { return MergedFaceSet.Count; } } /// @@ -447,7 +449,7 @@ public int NoOfFaces /// return index of vertices public IList IndexOuterboundOfFaceAt(int fIdx) { - return m_FacesCollDict[m_MergedFaceSet.ElementAt(fIdx)].IndexOuterBoundary; + return FacesCollDict[MergedFaceIndices[fIdx]].IndexOuterBoundary; } /// @@ -457,7 +459,7 @@ public IList IndexOuterboundOfFaceAt(int fIdx) /// List of list of the inner boundaries public IList> IndexInnerBoundariesOfFaceAt(int fIdx) { - return m_FacesCollDict[m_MergedFaceSet.ElementAt(fIdx)].IndexedInnerBoundaries; + return FacesCollDict[MergedFaceIndices[fIdx]].IndexedInnerBoundaries; } public static XYZ NormalByNewellMethod(IList vertices) @@ -506,9 +508,9 @@ public static XYZ NormalByNewellMethod(IList vertices) /// /// Combine coplanar triangles from the faceted body if they share the edge. From this process, polygonal faces (with or without holes) will be created /// - public void SimplifyAndMergeFaces(bool ignoreMerge = false) + public bool SimplifyAndMergeFaces(bool tryToMerge) { - int eulerBefore = ignoreMerge ? 0 : CalculateEulerCharacteristic(); + int eulerBefore = tryToMerge ? CalculateEulerCharacteristic() : 0; int noTriangle = GetTriangleCount(); IEqualityComparer normalComparer = new VectorCompare(); @@ -520,17 +522,17 @@ public void SimplifyAndMergeFaces(bool ignoreMerge = false) if (IsMesh) { - MeshTriangle f = m_MeshGeom.get_Triangle(ef); + MeshTriangle f = MeshGeom.get_Triangle(ef); vertIndex = new List(3) { (int)f.get_Index(0), (int)f.get_Index(1), (int)f.get_Index(2) }; } else { - TriangleInShellComponent f = m_Geom.GetTriangle(ef); + TriangleInShellComponent f = TriangulatedShell.GetTriangle(ef); vertIndex = new List(3) { f.VertexIndex0, f.VertexIndex1, f.VertexIndex2 }; } - IndexFace intF = new IndexFace(vertIndex, ref m_MeshVertices); - m_FacesCollDict.Add(faceIdxOffset++, intF); // Keep faces in a dictionary and assigns ID + IndexFace intF = new IndexFace(vertIndex, MeshVertices); + FacesCollDict.Add(FaceIdxOffset++, intF); // Keep faces in a dictionary and assigns ID List fIDList; if (!faceSortedByNormal.TryGetValue(intF.Normal, out fIDList)) @@ -549,8 +551,10 @@ public void SimplifyAndMergeFaces(bool ignoreMerge = false) List mergedFaceList = null; if (fListDict.Value.Count > 1) { - if (!ignoreMerge) + if (tryToMerge) + { TryMergeFaces(fListDict.Value, out mergedFaceList); + } else { // keep original face list @@ -561,21 +565,24 @@ public void SimplifyAndMergeFaces(bool ignoreMerge = false) // insert only new face indexes as the mergedlist from different vertices can be duplicated foreach (int fIdx in mergedFaceList) { - if (!m_MergedFaceSet.Contains(fIdx)) - m_MergedFaceSet.Add(fIdx); + if (!MergedFaceSet.Contains(fIdx)) + AddMergedFaceIndex(fIdx); } } } - else if (!m_MergedFaceSet.Contains(fListDict.Value[0])) - m_MergedFaceSet.Add(fListDict.Value[0]); // No pair face, add it into the mergedList + else if (!MergedFaceSet.Contains(fListDict.Value[0])) + { + AddMergedFaceIndex(fListDict.Value[0]); // No pair face, add it into the mergedList + } } // Remove unused vertices CleanVerticesAndUpdateIndexes(); - int eulerAfter = ignoreMerge ? 0 : CalculateEulerCharacteristic(); - if (eulerBefore != eulerAfter) - throw new InvalidOperationException(); // Coplanar merge broke the mesh in some way, so we need to fall back to exporting a triangular mesh + int eulerAfter = tryToMerge ? CalculateEulerCharacteristic() : 0; + // If eulerBefore != eulerAfter, coplanar merge broke the mesh in some way. + // We need to fall back to exporting a triangular mesh. + return (eulerBefore == eulerAfter); } /// @@ -585,31 +592,37 @@ void CleanVerticesAndUpdateIndexes() { List isolatedVertices = new List(); - if (m_MergedFaceSet.Count != 0) + if (MergedFaceSet.Count != 0) { HashSet vertices = new HashSet(); - foreach (int mergedFace in m_MergedFaceSet) + foreach (int mergedFace in MergedFaceSet) { - m_FacesCollDict[mergedFace].IndexOuterBoundary.ToList().ForEach(vt => vertices.Add(vt)); - if (m_FacesCollDict[mergedFace].IndexedInnerBoundaries != null) + FacesCollDict[mergedFace].IndexOuterBoundary.ToList().ForEach(vt => vertices.Add(vt)); + if (FacesCollDict[mergedFace].IndexedInnerBoundaries != null) { - foreach (IList innerB in m_FacesCollDict[mergedFace].IndexedInnerBoundaries) + foreach (IList innerB in FacesCollDict[mergedFace].IndexedInnerBoundaries) + { innerB.ToList().ForEach(vt => vertices.Add(vt)); + } } } - if (vertices.Count < m_MeshVertices.Count) - isolatedVertices = Enumerable.Range(0, m_MeshVertices.Count).Except(vertices).OrderBy(x => x).ToList(); + if (vertices.Count < MeshVertices.Count) + isolatedVertices = Enumerable.Range(0, MeshVertices.Count).Except(vertices).OrderBy(x => x).ToList(); } if (isolatedVertices.Count > 0) { foreach (int vertexInd in isolatedVertices) - m_MeshVertices.Remove(vertexInd); + { + MeshVertices.Remove(vertexInd); + } - foreach (IndexFace face in m_FacesCollDict.Values) + foreach (IndexFace face in FacesCollDict.Values) + { face.UpdateIndexes(isolatedVertices); + } } } /// @@ -621,7 +634,7 @@ void CleanVerticesAndUpdateIndexes() void TryMergeFaces(List inputFaceList, out List outputFaceList) { outputFaceList = new List(); - IndexFace firstF = m_FacesCollDict[inputFaceList[0]]; + IndexFace firstF = FacesCollDict[inputFaceList[0]]; int currProcFace = inputFaceList[0]; inputFaceList.RemoveAt(0); // remove the first face from the list bool merged = false; @@ -664,7 +677,7 @@ void TryMergeFaces(List inputFaceList, out List outputFaceList) else { currFaceIdx = pairedFace.Item1; - currFace = m_FacesCollDict[currFaceIdx]; + currFace = FacesCollDict[currFaceIdx]; // Need to reverse the face boundaries. Remove the entries in the Dict first, reverse the face, and add them back for (int cidx = 0; cidx < currFace.OuterAndInnerBoundaries.Count; ++cidx) @@ -693,7 +706,7 @@ void TryMergeFaces(List inputFaceList, out List outputFaceList) else { currFaceIdx = pairedFace.Item1; - currFace = m_FacesCollDict[currFaceIdx]; + currFace = FacesCollDict[currFaceIdx]; idx = pairedFace.Item2; } @@ -827,15 +840,18 @@ void TryMergeFaces(List inputFaceList, out List outputFaceList) // Find the largest loop and put it in the first position signifying the outer loop and the rest are the inner loops int largestPerimeterIdx = 0; double largestPerimeter = 0.0; - for (int i = 0; i < finalLoops.Count; i++) + for (int ii = 0; ii < finalLoops.Count; ii++) { double loopPerimeter = 0.0; - foreach (IndexSegment line in finalLoops[i]) - loopPerimeter += line.Extent (ref m_MeshVertices); + foreach (IndexSegment line in finalLoops[ii]) + { + loopPerimeter += line.Extent(MeshVertices); + } + if (loopPerimeter > largestPerimeter) { largestPerimeter = loopPerimeter; - largestPerimeterIdx = i; + largestPerimeterIdx = ii; } } // We need to move the largest loop into the head if it is not @@ -869,24 +885,24 @@ void TryMergeFaces(List inputFaceList, out List outputFaceList) } } - mergedFace = new IndexFace(newFaceVertsLoops, ref m_MeshVertices); + mergedFace = new IndexFace(newFaceVertsLoops, MeshVertices); inputFaceList.Remove(currFaceIdx); // Remove the merged face from segmentOfFaceDict - foreach (KeyValuePair idxSeg in m_FacesCollDict[currFaceIdx].OuterAndInnerBoundaries) + foreach (KeyValuePair idxSeg in FacesCollDict[currFaceIdx].OuterAndInnerBoundaries) { segmentOfFaceDict.Remove(idxSeg.Value); } - if (m_FacesCollDict.ContainsKey(currFaceIdx)) - m_FacesCollDict.Remove(currFaceIdx); + if (FacesCollDict.ContainsKey(currFaceIdx)) + FacesCollDict.Remove(currFaceIdx); merged = true; break; // Once there is an edge merged, create a new face and continue the process of merging } - int lastFaceID = faceIdxOffset++; // The new index is always the next one in the collection was inserted based on the seq order + int lastFaceID = FaceIdxOffset++; // The new index is always the next one in the collection was inserted based on the seq order if (mergedFace != null) - m_FacesCollDict.Add(lastFaceID, mergedFace); + FacesCollDict.Add(lastFaceID, mergedFace); if (!merged) { @@ -895,7 +911,7 @@ void TryMergeFaces(List inputFaceList, out List outputFaceList) if (inputFaceList.Count > 0) { - firstF = m_FacesCollDict[inputFaceList[0]]; + firstF = FacesCollDict[inputFaceList[0]]; // Remove the merged face from segmentOfFaceDict foreach (KeyValuePair idxSeg in firstF.OuterAndInnerBoundaries) @@ -918,8 +934,8 @@ void TryMergeFaces(List inputFaceList, out List outputFaceList) outputFaceList.Add(lastFaceID); // Remove merged face from the Dict - if (m_FacesCollDict.ContainsKey(currProcFace)) - m_FacesCollDict.Remove(currProcFace); + if (FacesCollDict.ContainsKey(currProcFace)) + FacesCollDict.Remove(currProcFace); if (inputFaceList.Count > 0) { @@ -944,10 +960,23 @@ void TryMergeFaces(List inputFaceList, out List outputFaceList) } } + /// + /// Appends the merged face index to the HashSet and List + /// We duplicate the indecies to List to have access by index in constant time. + /// The overhead for population and destruction of the list of integers isn't noticeable, + /// comparing to the speedup after removing ElementAt calls for HashSet + /// + /// The merged face index. + void AddMergedFaceIndex(int faceIdx) + { + MergedFaceSet.Add(faceIdx); + MergedFaceIndices.Add(faceIdx); + } + bool SegmentOfFaceToDict(ref IDictionary> segmentOfFaceDict, int indexFace) { IList entriesToRollback = new List(); - IndexFace theFace = m_FacesCollDict[indexFace]; + IndexFace theFace = FacesCollDict[indexFace]; try { int idx = 0; diff --git a/Source/Revit.IFC.Export/Utility/TypeObjectsCache.cs b/Source/Revit.IFC.Export/Utility/TypeObjectsCache.cs index 10fdc17a..fb244f81 100644 --- a/Source/Revit.IFC.Export/Utility/TypeObjectsCache.cs +++ b/Source/Revit.IFC.Export/Utility/TypeObjectsCache.cs @@ -38,7 +38,7 @@ public sealed class TypeObjectKey : Tuple + /// Extracts the unit handles to assign to a project + /// + /// Unit handles set + public static HashSet GetUnitsToAssign() + { + return ExporterCacheManager.UnitsCache.GetUnitsToAssign(); + } + + /// + /// Creates units spesific to ExportAsCOBIE + /// + public static void CreateCobieUnits() + { + if (!ExporterCacheManager.ExportOptionsCache.ExportAsCOBIE) + return; + + IFCFile file = ExporterCacheManager.ExporterIFC?.GetFile(); + if (file == null) + return; + + // Derived imperial mass unit + { + IFCUnit unitType = IFCUnit.MassUnit; + IFCAnyHandle dims = IFCInstanceExporter.CreateDimensionalExponents(file, 0, 1, 0, 0, 0, 0, 0); + double factor = 0.45359237; // --> pound to kilogram + string convName = "pound"; + + IFCAnyHandle kilogramUnit = IFCInstanceExporter.CreateSIUnit(file, IFCUnit.MassUnit, IFCSIPrefix.Kilo, IFCSIUnitName.Gram); + IFCAnyHandle convFactor = IFCInstanceExporter.CreateMeasureWithUnit(file, Toolkit.IFCDataUtil.CreateAsMassMeasure(factor), kilogramUnit); + IFCAnyHandle massUnit = IFCInstanceExporter.CreateConversionBasedUnit(file, dims, unitType, convName, convFactor); + ExporterCacheManager.UnitsCache.RegisterUnitInfo(SpecTypeId.Mass, new UnitInfo(massUnit, factor, 0.0)); + } + + // Air Changes per Hour + { + IFCUnit unitType = IFCUnit.FrequencyUnit; + IFCAnyHandle dims = IFCInstanceExporter.CreateDimensionalExponents(file, 0, 0, -1, 0, 0, 0, 0); + double factor = 1.0 / 3600.0; // --> seconds to hours + string convName = "ACH"; + + IFCAnyHandle secondUnit = IFCInstanceExporter.CreateSIUnit(file, IFCUnit.TimeUnit, null, IFCSIUnitName.Second); + IFCAnyHandle convFactor = IFCInstanceExporter.CreateMeasureWithUnit(file, Toolkit.IFCDataUtil.CreateAsTimeMeasure(factor), secondUnit); + IFCAnyHandle achUnit = IFCInstanceExporter.CreateConversionBasedUnit(file, dims, unitType, convName, convFactor); + ExporterCacheManager.UnitsCache.RegisterUserDefinedUnit("ACH", achUnit); + ExporterCacheManager.UnitsCache.RegisterUnitInfo(SpecTypeId.ElectricalFrequency, new UnitInfo(achUnit, factor, 0.0)); + } + + } + + /// + /// Get mapped Revit data type by ifc measure name + /// + public static ForgeTypeId GetUnitSpecTypeFromString(string measureName) + { + if (IfcToRevitDataTypeMapping.TryGetValue(measureName, out ForgeTypeId forgeTypeId)) + { + return forgeTypeId; + } + return null; + } + + /// + /// Create units for some special cases + /// + /// The file + /// Revit data type + /// Created unit handle + static UnitInfo CreateSpecialCases(IFCFile file, ForgeTypeId specTypeId) + { + UnitInfo unitInfo = null; + + if (specTypeId.Equals(SpecTypeId.Currency)) + { + // Specific IfcMonetaryUnit + unitInfo = CreateCurrencyUnit(file); + } + else if (specTypeId.Equals(SpecTypeId.ColorTemperature)) + { + // Color Temperature is in fact ThermoDynamicTemperature + // Create is specific way to avoid conflict with real HVACTemperature + unitInfo = CreateColorTemperatureUnit(file); + } + else if (specTypeId.Equals(SpecTypeId.MassPerUnitArea)) + { + // A single unit 'since ifc4'. + // Make more generic improvement if there are more than one such unit + if (!ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4) + { + DerivedAttributes attrib; + if (!DerivedUnitMapping.TryGetValue(specTypeId, out attrib)) + return null; + + attrib.ifcDrivedUnit = Toolkit.IFC4.IFCDerivedUnit.AREADENSITYUNIT; + attrib.userDefinedUnitName = string.Empty; + + return CreateUnitAsDerivedCommon(file, specTypeId, null, attrib); + } + } + + return unitInfo; + } + + /// + /// Creates spesific Currency unit + /// + static UnitInfo CreateCurrencyUnit(IFCFile file) + { + UnitInfo unitInfo = null; + + if (!ExporterCacheManager.ExportOptionsCache.ExportAs2x3CoordinationView2) + { + FormatOptions currencyFormatOptions = ExporterCacheManager.Document.GetUnits().GetFormatOptions(SpecTypeId.Currency); + ForgeTypeId currencySymbol = currencyFormatOptions.GetSymbolTypeId(); + + IFCAnyHandle currencyUnit = null; + + // Some of these are guesses for IFC2x3, since multiple currencies may use the same symbol, + // but no detail is given on which currency is being used. For IFC4, we just use the label. + if (!ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4) + { + string currencyLabel = null; + try + { + currencyLabel = LabelUtils.GetLabelForSymbol(currencySymbol); + currencyUnit = IFCInstanceExporter.CreateMonetaryUnit4(file, currencyLabel); + } + catch + { + currencyUnit = null; + } + } + else + { + IFCCurrencyType? currencyType = null; + + if (currencySymbol.Equals(SymbolTypeId.UsDollar)) + { + currencyType = IFCCurrencyType.USD; + } + else if (currencySymbol.Equals(SymbolTypeId.EuroPrefix) || + currencySymbol.Equals(SymbolTypeId.EuroSuffix)) + { + currencyType = IFCCurrencyType.EUR; + } + else if (currencySymbol.Equals(SymbolTypeId.UkPound)) + { + currencyType = IFCCurrencyType.GBP; + } + else if (currencySymbol.Equals(SymbolTypeId.ChineseHongKongDollar)) + { + currencyType = IFCCurrencyType.HKD; + } + else if (currencySymbol.Equals(SymbolTypeId.Krone)) + { + currencyType = IFCCurrencyType.NOK; + } + else if (currencySymbol.Equals(SymbolTypeId.Shekel)) + { + currencyType = IFCCurrencyType.ILS; + } + else if (currencySymbol.Equals(SymbolTypeId.Yen)) + { + currencyType = IFCCurrencyType.JPY; + } + else if (currencySymbol.Equals(SymbolTypeId.Won)) + { + currencyType = IFCCurrencyType.KRW; + } + else if (currencySymbol.Equals(SymbolTypeId.Baht)) + { + currencyType = IFCCurrencyType.THB; + } + else if (currencySymbol.Equals(SymbolTypeId.Dong)) + { + currencyType = IFCCurrencyType.VND; + } + + if (currencyType.HasValue) + currencyUnit = IFCInstanceExporter.CreateMonetaryUnit2x3(file, currencyType.Value); + } + + if (currencyUnit != null) + { + unitInfo = new UnitInfo(currencyUnit, 1.0, 0.0); + ExporterCacheManager.UnitsCache.RegisterUserDefinedUnit("CURRENCY", currencyUnit); + } + } + return unitInfo; + } + + /// + /// Creates spesific Color Temperature unit + /// + static UnitInfo CreateColorTemperatureUnit(IFCFile file) + { + UnitInfo unitInfo = null; + if (file == null) + return unitInfo; + + IFCAnyHandle colorTempUnit = IFCInstanceExporter.CreateSIUnit(file, IFCUnit.ThermoDynamicTemperatureUnit, null, IFCSIUnitName.Kelvin); + (double scaleFactor, double offset) = GetScaleFactorAndOffset(UnitTypeId.Kelvin); + ExporterCacheManager.UnitsCache.RegisterUserDefinedUnit("COLORTEMPERATURE", colorTempUnit); + + return new UnitInfo(colorTempUnit, scaleFactor, offset); + } + + + #region Classes to keep units attributes + /// + /// A structure to contain information about IfcSIUnit + /// + class SIUnitInfo + { + public SIUnitInfo(IFCSIUnitName inIfcSIUnitName, IFCSIPrefix? inIfcSIPrefix, bool inIsDefault) + { + ifcSIUnitName = inIfcSIUnitName; + ifcSIPrefix = inIfcSIPrefix; + isDefault = inIsDefault; + } + + readonly public IFCSIUnitName ifcSIUnitName; + readonly public IFCSIPrefix? ifcSIPrefix; + readonly public bool isDefault; + } + + /// + /// A structure to contain information about IfcSIUnit + /// + class SIAttributes + { + public SIAttributes(IFCUnit inIfcUnitType, IDictionary inSIUnitInfoDict) + { + ifcUnitType = inIfcUnitType; + siUnitInfoDict = inSIUnitInfoDict; + } + + readonly public IFCUnit ifcUnitType; + readonly public IDictionary siUnitInfoDict; + }; + + /// + /// A structure to contain information about IfcConversionBasedUnit + /// + class ConversionUnitInfo + { + public ConversionUnitInfo(string inConversionName, bool inIsDefault) + { + conversionName = inConversionName; + isDefault = inIsDefault; + } + + readonly public string conversionName; + readonly public bool isDefault; + } + + /// + /// A structure to contain information about IfcConversionBasedUnit + /// + class ConversionAttributes + { + public ConversionAttributes(IFCUnit inUnit, string inMeasureName, ForgeTypeId inBaseSI, int inLengthExponent, int inMassExponent, + int inTimeExponent, int inElectricCurrentExponent, int inThermodynamicTemperatureExponent, + int inAmountOfSubstanceExponent, int inLuminousIntensityExponent, IDictionary inConversionInfoDict) + { + ifcUnitType = inUnit; + measureName = inMeasureName; + baseSI = inBaseSI; + length = inLengthExponent; + mass = inMassExponent; + time = inTimeExponent; + electricCurrent = inElectricCurrentExponent; + thermodynamicTemperature = inThermodynamicTemperatureExponent; + amountOfSubstance = inAmountOfSubstanceExponent; + luminousIntensity = inLuminousIntensityExponent; + conversionInfoDict = inConversionInfoDict; + } + + readonly public IFCUnit ifcUnitType; + readonly public string measureName; + readonly public ForgeTypeId baseSI; + readonly public int length; + readonly public int mass; + readonly public int time; + readonly public int electricCurrent; + readonly public int thermodynamicTemperature; + readonly public int amountOfSubstance; + readonly public int luminousIntensity; + readonly public IDictionary conversionInfoDict; + + } + + /// + /// A structure to contain information about IfcDerivedUnit + /// + class DerivedInfo + { + public DerivedInfo(double? inExtraScale, bool inIsDefault, IList> inDerivedElements) + { + extraScale = inExtraScale; + isDefault = inIsDefault; + derivedElements = inDerivedElements; + } + + public double? extraScale; + public bool isDefault; + public IList> derivedElements; + } + + /// + /// A structure to contain information about IfcDerivedUnit + /// + class DerivedAttributes + { + public DerivedAttributes(Enum inDerivedUnitType, string inUserDefinedUnitName, IDictionary inDerivedInfoDict) + { + ifcDrivedUnit = inDerivedUnitType; + userDefinedUnitName = inUserDefinedUnitName; + derivedInfoDict = inDerivedInfoDict; + } + + + public Enum ifcDrivedUnit; + public string userDefinedUnitName; + public IDictionary derivedInfoDict; + } + #endregion + + + #region Unit creation methods + /// + /// Creates eighter selected in Revit or default ifc unit of apropriate type. + /// + /// The file + /// Revit data type + /// False - look for the mapping for selected Revit displayed unit. + /// True - look for the default unit in the mappings + /// Created unit handle + static UnitInfo CreateUnitFromMappings(IFCFile file, ForgeTypeId specTypeId, bool byDefault) + { + ForgeTypeId selectedUnitTypeId = null; + + if (!byDefault) + { + FormatOptions formatOptions = ExporterCacheManager.Document.GetUnits().GetFormatOptions(specTypeId); + selectedUnitTypeId = formatOptions.GetUnitTypeId(); + + if (selectedUnitTypeId == null) + return null; + } + + UnitInfo createdUnit = CreateUnitAsSI(file, specTypeId, selectedUnitTypeId); + + if (createdUnit == null) + createdUnit = CreateUnitAsConversionBased(file, specTypeId, selectedUnitTypeId); + + if (createdUnit == null) + createdUnit = CreateUnitAsDerived(file, specTypeId, selectedUnitTypeId); + + return createdUnit; + } + + /// + /// Creates IfcSIUnit handle for input data/unit types if present in mapping. + /// If unit type is null - look for default unit. + /// + /// The file + /// Revit data type + /// Revit unit type + /// Created unit handle + static UnitInfo CreateUnitAsSI(IFCFile file, ForgeTypeId specTypeId, ForgeTypeId selectedUnitTypeId) + { + if (file == null) + return null; + + SIAttributes attrib; + if (!SIUnitMapping.TryGetValue(specTypeId, out attrib)) + return null; + + if (attrib.siUnitInfoDict == null) + return null; + + ForgeTypeId unitTypeId = null; + IFCSIUnitName ifcSIUnitName = 0; + IFCSIPrefix? ifcSIPrefix = null; + IFCUnit ifcUnit; + + if (selectedUnitTypeId == null) + { + // Look for default unit + foreach (var pair in attrib.siUnitInfoDict) + { + if (pair.Value.isDefault) + { + unitTypeId = pair.Key; + ifcSIUnitName = pair.Value.ifcSIUnitName; + ifcSIPrefix = pair.Value.ifcSIPrefix; + break; + } + } + } + else + { + SIUnitInfo siInfo = null; + if (attrib.siUnitInfoDict.TryGetValue(selectedUnitTypeId, out siInfo)) + { + unitTypeId = selectedUnitTypeId; + ifcSIUnitName = siInfo.ifcSIUnitName; + ifcSIPrefix = siInfo.ifcSIPrefix; + } + } + ifcUnit = attrib.ifcUnitType; + + if (unitTypeId == null) + return null; + + + + IFCAnyHandle siUnit = IFCInstanceExporter.CreateSIUnit(file, ifcUnit, ifcSIPrefix, ifcSIUnitName); + (double scaleFactor, double offset) = GetScaleFactorAndOffset(unitTypeId); + return new UnitInfo(siUnit, scaleFactor, offset); + } + + /// + /// Creates IfcConversionBasedUnit handle for input data/unit types if present in mapping. + /// If unit type is null - look for default unit. + /// + /// The file + /// Revit data type + /// Revit unit type + /// Created unit handle + static UnitInfo CreateUnitAsConversionBased(IFCFile file, ForgeTypeId specTypeId, ForgeTypeId selectedUnitTypeId) + { + if (file == null) + return null; + + ConversionAttributes attrib; + if (!ConversionBasedUnitMapping.TryGetValue(specTypeId, out attrib)) + return null; + + if (attrib.conversionInfoDict == null) + return null; + + ForgeTypeId unitTypeId = null; + IFCUnit ifcUnit; + string ifcMeasureName = null; + ForgeTypeId baseTypeId = null; + + int length = 0; + int mass = 0; + int time = 0; + int electricCurrent = 0; + int thermodynamicTemperature = 0; + int amountOfSubstance = 0; + int luminousIntensity = 0; + + string conversionName = null; + + if (selectedUnitTypeId == null) + { + // Look for default unit + foreach (var pair in attrib.conversionInfoDict) + { + if (pair.Value.isDefault) + { + unitTypeId = pair.Key; + conversionName = pair.Value.conversionName; + break; + } + } + } + else + { + ConversionUnitInfo conversionInfo = null; + if (attrib.conversionInfoDict.TryGetValue(selectedUnitTypeId, out conversionInfo)) + { + unitTypeId = selectedUnitTypeId; + conversionName = conversionInfo.conversionName; + } + } + ifcUnit = attrib.ifcUnitType; + ifcMeasureName = attrib.measureName; + baseTypeId = attrib.baseSI; + + length = attrib.length; + mass = attrib.mass; + time = attrib.time; + electricCurrent = attrib.electricCurrent; + thermodynamicTemperature = attrib.thermodynamicTemperature; + amountOfSubstance = attrib.amountOfSubstance; + luminousIntensity = attrib.luminousIntensity; + + conversionName = GetCobieUnitName(conversionName); + + if (unitTypeId == null) + return null; + + IFCAnyHandle siBaseUnit = GetOrCreateAuxiliaryUnit(file, baseTypeId); + if (siBaseUnit == null) + return null; + + double siScaleFactor = UnitUtils.Convert(1.0, unitTypeId, baseTypeId); + IFCAnyHandle dims = IFCInstanceExporter.CreateDimensionalExponents(file, length, mass, time, electricCurrent, thermodynamicTemperature, amountOfSubstance, luminousIntensity); + IFCAnyHandle conversionFactor = IFCInstanceExporter.CreateMeasureWithUnit(file, IFCDataUtil.CreateAsMeasure(siScaleFactor, ifcMeasureName), siBaseUnit); + IFCAnyHandle conversionUnit = IFCInstanceExporter.CreateConversionBasedUnit(file, dims, ifcUnit, conversionName, conversionFactor); + + double scaleFactor = UnitUtils.ConvertFromInternalUnits(1.0, unitTypeId); + return new UnitInfo(conversionUnit, scaleFactor, 0.0); + } + + /// + /// Creates IfcDerivedUnit handle for input data/unit types if present in mapping. + /// If unit type is null - look for default unit. + /// + /// The file + /// Revit data type + /// Revit unit type + /// Created unit handle + static UnitInfo CreateUnitAsDerived(IFCFile file, ForgeTypeId specTypeId, ForgeTypeId selectedUnitTypeId) + { + DerivedAttributes attrib; + if (!DerivedUnitMapping.TryGetValue(specTypeId, out attrib)) + return null; + + if (attrib.derivedInfoDict == null) + return null; + + return CreateUnitAsDerivedCommon(file, specTypeId, selectedUnitTypeId, attrib); + } + + /// + /// Creates IfcDerivedUnit handle for input data/unit types if present in mapping. + /// If unit type is null - look for default unit. + /// + /// The file + /// Revit data type + /// Revit unit type + /// Derived unit attributes + /// Created unit handle + static UnitInfo CreateUnitAsDerivedCommon(IFCFile file, ForgeTypeId specTypeId, ForgeTypeId selectedUnitTypeId, DerivedAttributes attrib) + { + if (file == null) + return null; + + ForgeTypeId unitTypeId = null; + string userDefName = null; + double? extraScale = null; + IList> derivedElements = null; + + if (selectedUnitTypeId == null) + { + // Look for default unit + foreach (var pair in attrib.derivedInfoDict) + { + if (pair.Value.isDefault) + { + unitTypeId = pair.Key; + extraScale = pair.Value.extraScale; + derivedElements = pair.Value.derivedElements; + break; + } + } + } + else + { + DerivedInfo derivedInfo = null; + if (attrib.derivedInfoDict.TryGetValue(selectedUnitTypeId, out derivedInfo)) + { + unitTypeId = selectedUnitTypeId; + extraScale = derivedInfo.extraScale; + derivedElements = derivedInfo.derivedElements; + } + } + Enum ifcDerivedUnit = attrib.ifcDrivedUnit; + userDefName = attrib.userDefinedUnitName; + + if (unitTypeId == null || (derivedElements?.Count ?? 0) == 0) + return null; + + ISet elements = new HashSet(); + foreach (var pair in derivedElements) + { + IFCAnyHandle baseSIUnit = GetOrCreateAuxiliaryUnit(file, pair.Item1); + if (baseSIUnit == null) + return null; + + elements.Add(GetOrCreateDerivedUnitElement(file, baseSIUnit, pair.Item2)); + } + + IFCAnyHandle derivedUnitHnd = IFCInstanceExporter.CreateDerivedUnit(file, elements, ifcDerivedUnit, userDefName); + + if (!string.IsNullOrEmpty(userDefName)) + { + string capitalName = NamingUtil.RemoveSpaces(userDefName.ToUpper()); + ExporterCacheManager.UnitsCache.RegisterUserDefinedUnit(capitalName, derivedUnitHnd); + } + + double scaleFactor = UnitUtils.ConvertFromInternalUnits(1.0, unitTypeId); + scaleFactor *= extraScale.HasValue ? extraScale.Value : 1.0; + return new UnitInfo(derivedUnitHnd, scaleFactor, 0.0); + + } + + /// + /// Creates IfcDerivedUnitElement handle with caching + /// If unit type is null - look for default unit. + /// + /// The file + /// Unit handle + /// The exponent + /// Created IfcDerivedUnitElement handle + static IFCAnyHandle GetOrCreateDerivedUnitElement(IFCFile file, IFCAnyHandle unit, int exponent) + { + Tuple pair = Tuple.Create(unit, exponent); + IFCAnyHandle derivedUnitElement = null; + if (!ExporterCacheManager.UnitsCache.FindDerivedUnitElement(pair, out derivedUnitElement)) + { + derivedUnitElement = IFCInstanceExporter.CreateDerivedUnitElement(file, unit, exponent); + ExporterCacheManager.UnitsCache.RegisterDerivedUnit(pair, derivedUnitElement); + } + return derivedUnitElement; + } + + /// + /// Creates auxiliary unit handle with caching if present in mapping + /// + /// The file + /// Revit unit type + /// Auxiliary unit handle + static IFCAnyHandle GetOrCreateAuxiliaryUnit(IFCFile file, ForgeTypeId unitTypeId) + { + IFCAnyHandle auxiliaryUnit = null; + if (ExporterCacheManager.UnitsCache.FindAuxiliaryUnit(unitTypeId, out auxiliaryUnit)) + return auxiliaryUnit; + + Tuple ifcAuxilaryValue = null; + if (AuxiliaryUnitMapping.TryGetValue(unitTypeId, out ifcAuxilaryValue) == false) + return null; + + auxiliaryUnit = IFCInstanceExporter.CreateSIUnit(file, ifcAuxilaryValue.Item3, ifcAuxilaryValue.Item2, ifcAuxilaryValue.Item1); + + ExporterCacheManager.UnitsCache.RegisterAuxiliaryUnit(unitTypeId, auxiliaryUnit); + + return auxiliaryUnit; + } + + /// + /// Calculates scaling and offset values for conversion + /// from Revit internal units + /// + /// Revit unit type + /// Auxiliary unit handle + static (double offset, double scaleFactor) GetScaleFactorAndOffset(ForgeTypeId unitTypeId) + { + double value0 = UnitUtils.ConvertFromInternalUnits(0.0, unitTypeId); + double value1 = UnitUtils.ConvertFromInternalUnits(1.0, unitTypeId); + + double offset = value0; + double scaleFactor = (value1 - value0); + if (MathUtil.IsAlmostZero(scaleFactor)) + scaleFactor = 1.0; + + return (scaleFactor, offset); + } + + /// + /// Get mapped unit name for ExportAsCOBIE + /// + static string GetCobieUnitName(string unitName) + { + if (!ExporterCacheManager.ExportOptionsCache.ExportAsCOBIE) + return unitName; + + string cobieName; + if (!CobieUnitNameMapping.TryGetValue(unitName, out cobieName)) + cobieName = unitName.ToLower(); + + return cobieName; + } + + #endregion + + + #region Unit Mapping Tables + /// + /// The dictionary contains the information to create auxiliary ifc unit for a Revit unit type + /// These are the auxiliary unit handles that don't go to IfcUnitAssignment + /// + private static readonly Dictionary> AuxiliaryUnitMapping = new Dictionary>() + { + { UnitTypeId.Meters, Tuple.Create(IFCSIUnitName.Metre, null, IFCUnit.LengthUnit) }, + { UnitTypeId.Decimeters, Tuple.Create(IFCSIUnitName.Metre, IFCSIPrefix.Deci, IFCUnit.LengthUnit) }, + { UnitTypeId.SquareMeters, Tuple.Create(IFCSIUnitName.Square_Metre, null, IFCUnit.AreaUnit) }, + { UnitTypeId.CubicMeters, Tuple.Create(IFCSIUnitName.Cubic_Metre, null, IFCUnit.VolumeUnit) }, + { UnitTypeId.Kilograms, Tuple.Create(IFCSIUnitName.Gram, IFCSIPrefix.Kilo, IFCUnit.MassUnit) }, + { UnitTypeId.Seconds, Tuple.Create(IFCSIUnitName.Second, null, IFCUnit.TimeUnit) }, + { UnitTypeId.Amperes, Tuple.Create(IFCSIUnitName.Ampere, null, IFCUnit.ElectricCurrentUnit) }, + { UnitTypeId.Kelvin, Tuple.Create(IFCSIUnitName.Kelvin, null, IFCUnit.ThermoDynamicTemperatureUnit) }, + { UnitTypeId.Candelas, Tuple.Create(IFCSIUnitName.Candela, null, IFCUnit.LuminousIntensityUnit) }, + { UnitTypeId.Radians, Tuple.Create(IFCSIUnitName.Radian, null, IFCUnit.PlaneAngleUnit) }, + { UnitTypeId.Lumens, Tuple.Create(IFCSIUnitName.Lumen, null, IFCUnit.LuminousFluxUnit) }, + { UnitTypeId.Newtons, Tuple.Create(IFCSIUnitName.Newton, null, IFCUnit.ForceUnit) }, + + }; + + + /// + /// The dictionary contains the information to create IfcSIUnit for a Revit data type + /// + private static readonly Dictionary SIUnitMapping = new Dictionary() + { + { SpecTypeId.Mass, new SIAttributes(IFCUnit.MassUnit, new Dictionary() + { + { UnitTypeId.Kilograms, new SIUnitInfo(IFCSIUnitName.Gram, IFCSIPrefix.Kilo, true) } + } ) + }, + { SpecTypeId.Time, new SIAttributes(IFCUnit.TimeUnit, new Dictionary() + { + { UnitTypeId.Seconds, new SIUnitInfo(IFCSIUnitName.Second, null, true) } + } ) + }, + { SpecTypeId.Current, new SIAttributes(IFCUnit.ElectricCurrentUnit, new Dictionary() + { + { UnitTypeId.Amperes, new SIUnitInfo(IFCSIUnitName.Ampere, null, true) } + } ) + }, + { SpecTypeId.LuminousIntensity, new SIAttributes(IFCUnit.LuminousIntensityUnit, new Dictionary() + { + { UnitTypeId.Candelas, new SIUnitInfo(IFCSIUnitName.Candela, null, true) } + } ) + }, + { SpecTypeId.HvacTemperature, new SIAttributes(IFCUnit.ThermoDynamicTemperatureUnit, new Dictionary() + { + { UnitTypeId.Celsius, new SIUnitInfo(IFCSIUnitName.Degree_Celsius, null, true) }, + { UnitTypeId.Kelvin, new SIUnitInfo(IFCSIUnitName.Kelvin, null, false) } + } ) + }, + { SpecTypeId.Length, new SIAttributes(IFCUnit.LengthUnit, new Dictionary() + { + { UnitTypeId.Meters, new SIUnitInfo(IFCSIUnitName.Metre, null, false) }, + { UnitTypeId.MetersCentimeters, new SIUnitInfo(IFCSIUnitName.Metre, null, false) }, + { UnitTypeId.Centimeters, new SIUnitInfo(IFCSIUnitName.Metre, IFCSIPrefix.Centi, false) }, + { UnitTypeId.Millimeters, new SIUnitInfo(IFCSIUnitName.Metre, IFCSIPrefix.Milli, false) } + } ) + }, + { SpecTypeId.Area, new SIAttributes(IFCUnit.AreaUnit, new Dictionary() + { + { UnitTypeId.SquareMeters, new SIUnitInfo(IFCSIUnitName.Square_Metre, null, false) }, + { UnitTypeId.SquareCentimeters, new SIUnitInfo(IFCSIUnitName.Square_Metre, IFCSIPrefix.Centi, false) }, + { UnitTypeId.Millimeters, new SIUnitInfo(IFCSIUnitName.Square_Metre, IFCSIPrefix.Milli, false) } + } ) + }, + { SpecTypeId.Volume, new SIAttributes(IFCUnit.VolumeUnit, new Dictionary() + { + { UnitTypeId.CubicMeters, new SIUnitInfo(IFCSIUnitName.Cubic_Metre, null, false) }, + { UnitTypeId.Liters, new SIUnitInfo(IFCSIUnitName.Cubic_Metre, IFCSIPrefix.Deci, false) }, + { UnitTypeId.CubicCentimeters, new SIUnitInfo(IFCSIUnitName.Cubic_Metre, IFCSIPrefix.Centi, false) }, + { UnitTypeId.CubicMillimeters, new SIUnitInfo(IFCSIUnitName.Cubic_Metre, IFCSIPrefix.Milli, false) } + } ) + }, + { SpecTypeId.Angle, new SIAttributes(IFCUnit.PlaneAngleUnit, new Dictionary() + { + { UnitTypeId.Radians, new SIUnitInfo(IFCSIUnitName.Radian, null, false) } + } ) + }, + { SpecTypeId.Force, new SIAttributes(IFCUnit.ForceUnit, new Dictionary() + { + { UnitTypeId.Newtons, new SIUnitInfo(IFCSIUnitName.Newton, null, true) }, + { UnitTypeId.Dekanewtons, new SIUnitInfo(IFCSIUnitName.Newton, IFCSIPrefix.Deca, false) }, + { UnitTypeId.Kilonewtons, new SIUnitInfo(IFCSIUnitName.Newton, IFCSIPrefix.Kilo, false) }, + { UnitTypeId.Meganewtons, new SIUnitInfo(IFCSIUnitName.Newton, IFCSIPrefix.Mega, false) } + } ) + }, + { SpecTypeId.ElectricalFrequency, new SIAttributes(IFCUnit.FrequencyUnit, new Dictionary() + { + { UnitTypeId.Hertz, new SIUnitInfo(IFCSIUnitName.Hertz, null, true) } + } ) + }, + { SpecTypeId.ElectricalPotential, new SIAttributes(IFCUnit.ElectricVoltageUnit, new Dictionary() + { + { UnitTypeId.Volts, new SIUnitInfo(IFCSIUnitName.Volt, null, true) } + } ) + }, + { SpecTypeId.HvacPower, new SIAttributes(IFCUnit.PowerUnit, new Dictionary() + { + { UnitTypeId.Watts, new SIUnitInfo(IFCSIUnitName.Watt, null, true) } + } ) + }, + { SpecTypeId.Illuminance, new SIAttributes(IFCUnit.IlluminanceUnit, new Dictionary() + { + { UnitTypeId.Lux, new SIUnitInfo(IFCSIUnitName.Lux, null, true) } + } ) + }, + { SpecTypeId.LuminousFlux, new SIAttributes(IFCUnit.LuminousFluxUnit, new Dictionary() + { + { UnitTypeId.Lumens, new SIUnitInfo(IFCSIUnitName.Lumen, null, true) } + } ) + }, + { SpecTypeId.Energy, new SIAttributes(IFCUnit.EnergyUnit, new Dictionary() + { + { UnitTypeId.Joules, new SIUnitInfo(IFCSIUnitName.Joule, null, true) } + } ) + }, + { SpecTypeId.HvacPressure, new SIAttributes(IFCUnit.PressureUnit, new Dictionary() + { + { UnitTypeId.Pascals, new SIUnitInfo(IFCSIUnitName.Pascal, null, true) }, + { UnitTypeId.Kilopascals, new SIUnitInfo(IFCSIUnitName.Pascal, IFCSIPrefix.Kilo, false) }, + { UnitTypeId.Megapascals, new SIUnitInfo(IFCSIUnitName.Pascal, IFCSIPrefix.Mega, false) } + } ) + } + }; + + + /// + /// The dictionary contains the information to create IfcConversionBasedUnit for a Revit data type + /// + private static readonly Dictionary ConversionBasedUnitMapping = new Dictionary() + { + { SpecTypeId.Length, new ConversionAttributes(IFCUnit.LengthUnit, "IfcLengthMeasure", UnitTypeId.Meters, 1, 0, 0, 0, 0, 0, 0, new Dictionary() { + { UnitTypeId.Feet, new ConversionUnitInfo("FOOT", true) }, + { UnitTypeId.FeetFractionalInches, new ConversionUnitInfo("FOOT", false)}, + { UnitTypeId.Inches, new ConversionUnitInfo("INCH", false)}, + { UnitTypeId.FractionalInches, new ConversionUnitInfo("INCH", false) } } ) + }, + { SpecTypeId.Area, new ConversionAttributes(IFCUnit.AreaUnit, "IfcAreaMeasure", UnitTypeId.SquareMeters, 2, 0, 0, 0, 0, 0, 0, new Dictionary() { + { UnitTypeId.SquareFeet, new ConversionUnitInfo("SQUARE FOOT", true) }, + { UnitTypeId.SquareInches, new ConversionUnitInfo("SQUARE INCH", false) } } ) + }, + { SpecTypeId.Volume, new ConversionAttributes(IFCUnit.VolumeUnit, "IfcVolumeMeasure", UnitTypeId.CubicMeters, 3, 0, 0, 0, 0, 0, 0, new Dictionary() { + { UnitTypeId.CubicFeet, new ConversionUnitInfo("CUBIC FOOT", true) }, + { UnitTypeId.CubicInches, new ConversionUnitInfo("CUBIC INCH", false) } } ) + }, + { SpecTypeId.Angle, new ConversionAttributes(IFCUnit.PlaneAngleUnit, "IfcPlaneAngleMeasure", UnitTypeId.Radians, 0, 0, 0, 0, 0, 0, 0, new Dictionary() { + { UnitTypeId.Degrees, new ConversionUnitInfo("DEGREE", true) }, + { UnitTypeId.DegreesMinutes, new ConversionUnitInfo("DEGREE", false) }, + { UnitTypeId.Gradians, new ConversionUnitInfo("GRAD", false) } } ) + }, + { SpecTypeId.Force, new ConversionAttributes(IFCUnit.ForceUnit, "IfcForceMeasure", UnitTypeId.Newtons, 1, 1, -2, 0, 0, 0, 0, new Dictionary() { + { UnitTypeId.KilogramsForce, new ConversionUnitInfo("KILOGRAM-FORCE", false) }, + { UnitTypeId.TonnesForce, new ConversionUnitInfo("TONN-FORCE", false) }, + { UnitTypeId.UsTonnesForce, new ConversionUnitInfo("USTONN-FORCE", false) }, + { UnitTypeId.PoundsForce, new ConversionUnitInfo("POUND-FORCE", false) }, + { UnitTypeId.Kips, new ConversionUnitInfo("CUBIC INCH", false) } } ) + } + }; + + /// + /// The dictionary contains the information to create IfcDerivedUnit for a Revit data type + /// + private static readonly Dictionary DerivedUnitMapping = new Dictionary() + { + { SpecTypeId.MassDensity, new DerivedAttributes(IFCDerivedUnitEnum.MassDensityUnit, null, new Dictionary() { + { UnitTypeId.KilogramsPerCubicMeter, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, 1), + Tuple.Create(UnitTypeId.Meters, -3) } ) + } } ) + }, + { SpecTypeId.PipingDensity, new DerivedAttributes(IFCDerivedUnitEnum.IonConcentrationUnit, null, new Dictionary() { + { UnitTypeId.KilogramsPerCubicMeter, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, 1), + Tuple.Create(UnitTypeId.Meters, -3) } ) + } } ) + }, + { SpecTypeId.MomentOfInertia, new DerivedAttributes(IFCDerivedUnitEnum.MomentOfInertiaUnit, null, new Dictionary() { + { UnitTypeId.MetersToTheFourthPower, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Meters, 4) } ) + } } ) + }, + { SpecTypeId.HeatTransferCoefficient, new DerivedAttributes(IFCDerivedUnitEnum.ThermalTransmittanceUnit, null, new Dictionary() { + { UnitTypeId.WattsPerSquareMeterKelvin, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, 1), + Tuple.Create(UnitTypeId.Kelvin, -1), + Tuple.Create(UnitTypeId.Seconds, -3) } ) + } } ) + }, + { SpecTypeId.ThermalConductivity, new DerivedAttributes(IFCDerivedUnitEnum.ThermalConductanceUnit, null, new Dictionary() { + { UnitTypeId.WattsPerMeterKelvin, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, 1), + Tuple.Create(UnitTypeId.Meters, 1), + Tuple.Create(UnitTypeId.Kelvin, -1), + Tuple.Create(UnitTypeId.Seconds, -3) } ) + } } ) + }, + { SpecTypeId.AirFlow, new DerivedAttributes(IFCDerivedUnitEnum.VolumetricFlowRateUnit, null, new Dictionary() { + { UnitTypeId.CubicMetersPerSecond, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Meters, 3), + Tuple.Create(UnitTypeId.Seconds, -1) } ) + }, + { UnitTypeId.LitersPerSecond, new DerivedInfo(null, false, new List>() { + Tuple.Create(UnitTypeId.Decimeters, 3), + Tuple.Create(UnitTypeId.Seconds, -1) } ) + } } ) + }, + { SpecTypeId.PipingMassPerTime, new DerivedAttributes(IFCDerivedUnitEnum.MassFlowRateUnit, null, new Dictionary() { + { UnitTypeId.KilogramsPerSecond, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, 1), + Tuple.Create(UnitTypeId.Seconds, -1) } ) + } } ) + }, + { SpecTypeId.AngularSpeed, new DerivedAttributes(IFCDerivedUnitEnum.RotationalFrequencyUnit, null, new Dictionary() { + { UnitTypeId.RevolutionsPerSecond, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Seconds, -1) } ) + } } ) + }, + { SpecTypeId.Wattage, new DerivedAttributes(IFCDerivedUnitEnum.SoundPowerUnit, null, new Dictionary() { + { UnitTypeId.Watts, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, 1), + Tuple.Create(UnitTypeId.Meters, 2), + Tuple.Create(UnitTypeId.Seconds, -3) } ) + } } ) + }, + { SpecTypeId.HvacPressure, new DerivedAttributes(IFCDerivedUnitEnum.SoundPressureUnit, null, new Dictionary() { + { UnitTypeId.Pascals, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, 1), + Tuple.Create(UnitTypeId.Meters, -1), + Tuple.Create(UnitTypeId.Seconds, -2) } ) + } } ) + }, + { SpecTypeId.HvacVelocity, new DerivedAttributes(IFCDerivedUnitEnum.LinearVelocityUnit, null, new Dictionary() { + { UnitTypeId.MetersPerSecond, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Meters, 1), + Tuple.Create(UnitTypeId.Seconds, -1) } ) + } } ) + }, + { SpecTypeId.LinearForce, new DerivedAttributes(IFCDerivedUnitEnum.LinearForceUnit, null, new Dictionary() { + { UnitTypeId.NewtonsPerMeter, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, 1), + Tuple.Create(UnitTypeId.Seconds, -2) } ) + } } ) + }, + { SpecTypeId.AreaForce, new DerivedAttributes(IFCDerivedUnitEnum.PlanarForceUnit, null, new Dictionary() { + { UnitTypeId.NewtonsPerSquareMeter, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, 1), + Tuple.Create(UnitTypeId.Meters, -1), + Tuple.Create(UnitTypeId.Seconds, -2) } ) + } } ) + }, + { SpecTypeId.SpecificHeat, new DerivedAttributes(IFCDerivedUnitEnum.SpecificHeatCapacityUnit, null, new Dictionary() { + { UnitTypeId.JoulesPerKilogramDegreeCelsius, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Meters, 2), + Tuple.Create(UnitTypeId.Seconds, -2), + Tuple.Create(UnitTypeId.Kelvin, -1) } ) + } } ) + }, + { SpecTypeId.HvacPowerDensity, new DerivedAttributes(IFCDerivedUnitEnum.HeatFluxDensityUnit, null, new Dictionary() { + { UnitTypeId.WattsPerSquareMeter, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, 1), + Tuple.Create(UnitTypeId.Seconds, -3) } ) + } } ) + }, + { SpecTypeId.SpecificHeatOfVaporization, new DerivedAttributes(IFCDerivedUnitEnum.HeatingValueUnit, null, new Dictionary() { + { UnitTypeId.JoulesPerGram, new DerivedInfo(1.0e+3, true, new List>() { + Tuple.Create(UnitTypeId.Meters, 2), + Tuple.Create(UnitTypeId.Seconds, -2) } ) + } } ) + }, + { SpecTypeId.Permeability, new DerivedAttributes(IFCDerivedUnitEnum.VaporPermeabilityUnit, null, new Dictionary() { + { UnitTypeId.NanogramsPerPascalSecondSquareMeter, new DerivedInfo(1.0e-12, true, new List>() { + Tuple.Create(UnitTypeId.Meters, -1), + Tuple.Create(UnitTypeId.Seconds, 1) } ) + } } ) + }, + { SpecTypeId.HvacViscosity, new DerivedAttributes(IFCDerivedUnitEnum.DynamicViscosityUnit, null, new Dictionary() { + { UnitTypeId.KilogramsPerMeterSecond, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, 1), + Tuple.Create(UnitTypeId.Meters, -1), + Tuple.Create(UnitTypeId.Seconds, -1) } ) + } } ) + }, + { SpecTypeId.ThermalExpansionCoefficient, new DerivedAttributes(IFCDerivedUnitEnum.ThermalExpansionCoefficientUnit, null, new Dictionary() { + { UnitTypeId.InverseDegreesCelsius, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Kelvin, -1) } ) + } } ) + }, + { SpecTypeId.Stress, new DerivedAttributes(IFCDerivedUnitEnum.ModulusOfElasticityUnit, null, new Dictionary() { + { UnitTypeId.Pascals, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, 1), + Tuple.Create(UnitTypeId.Meters, -1), + Tuple.Create(UnitTypeId.Seconds, -2) } ) + } } ) + }, + { SpecTypeId.IsothermalMoistureCapacity, new DerivedAttributes(IFCDerivedUnitEnum.IsothermalMoistureCapacityUnit, null, new Dictionary() { + { UnitTypeId.CubicMetersPerKilogram, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, -1), + Tuple.Create(UnitTypeId.Meters, 3) } ) + } } ) + }, + + { SpecTypeId.Diffusivity, new DerivedAttributes(IFCDerivedUnitEnum.MoistureDiffusivityUnit, null, new Dictionary() { + { UnitTypeId.SquareMetersPerSecond, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Meters, 2), + Tuple.Create(UnitTypeId.Seconds, -1) } ) + } } ) + }, + { SpecTypeId.MassPerUnitLength, new DerivedAttributes(IFCDerivedUnitEnum.MassPerLengthUnit, null, new Dictionary() { + { UnitTypeId.KilogramsPerMeter, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, 1), + Tuple.Create(UnitTypeId.Meters, -1) } ) + } } ) + }, + { SpecTypeId.ThermalResistance, new DerivedAttributes(IFCDerivedUnitEnum.ThermalResistanceUnit, null, new Dictionary() { + { UnitTypeId.SquareMeterKelvinsPerWatt, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, -1), + Tuple.Create(UnitTypeId.Seconds, 3), + Tuple.Create(UnitTypeId.Kelvin, 1) } ) + } } ) + }, + { SpecTypeId.Acceleration, new DerivedAttributes(IFCDerivedUnitEnum.AccelerationUnit, null, new Dictionary() { + { UnitTypeId.MetersPerSecondSquared, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Meters, 1), + Tuple.Create(UnitTypeId.Seconds, -2) } ) + } } ) + }, + { SpecTypeId.Pulsation, new DerivedAttributes(IFCDerivedUnitEnum.AngularVelocityUnit, null, new Dictionary() { + { UnitTypeId.RadiansPerSecond, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Radians, 1), + Tuple.Create(UnitTypeId.Seconds, -1) } ) + } } ) + }, + { SpecTypeId.PointSpringCoefficient, new DerivedAttributes(IFCDerivedUnitEnum.LinearStiffnessUnit, null, new Dictionary() { + { UnitTypeId.NewtonsPerMeter, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, 1), + Tuple.Create(UnitTypeId.Seconds, -2) } ) + } } ) + }, + { SpecTypeId.WarpingConstant, new DerivedAttributes(IFCDerivedUnitEnum.WarpingConstantUnit, null, new Dictionary() { + { UnitTypeId.MetersToTheSixthPower, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Meters, 6) } ) + } } ) + }, + { SpecTypeId.LinearMoment, new DerivedAttributes(IFCDerivedUnitEnum.LinearMomentUnit, null, new Dictionary() { + { UnitTypeId.NewtonMetersPerMeter, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, 1), + Tuple.Create(UnitTypeId.Meters, 1), + Tuple.Create(UnitTypeId.Seconds, -2) } ) + } } ) + }, + { SpecTypeId.Moment, new DerivedAttributes(IFCDerivedUnitEnum.Torqueunit, null, new Dictionary() { + { UnitTypeId.NewtonMeters, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, 1), + Tuple.Create(UnitTypeId.Meters, 2), + Tuple.Create(UnitTypeId.Seconds, -2) } ) + } } ) + }, + { SpecTypeId.CostPerArea, new DerivedAttributes(IFCDerivedUnitEnum.UserDefined, "Cost Per Area", new Dictionary() { + { UnitTypeId.CurrencyPerSquareMeter, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Meters, -2) } ) + } } ) + }, + { SpecTypeId.ApparentPowerDensity, new DerivedAttributes(IFCDerivedUnitEnum.UserDefined, "Apparent Power Density", new Dictionary() { + { UnitTypeId.VoltAmperesPerSquareMeter, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, 1), + Tuple.Create(UnitTypeId.Seconds, -3) } ) + } } ) + }, + { SpecTypeId.CostRateEnergy, new DerivedAttributes(IFCDerivedUnitEnum.UserDefined, "Cost Rate Energy", new Dictionary() { + { UnitTypeId.CurrencyPerWattHour, new DerivedInfo(1.0 / 3600.0, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, -1), + Tuple.Create(UnitTypeId.Meters, -2), + Tuple.Create(UnitTypeId.Seconds, 2) } ) + } } ) + }, + { SpecTypeId.CostRatePower, new DerivedAttributes(IFCDerivedUnitEnum.UserDefined, "Cost Rate Power", new Dictionary() { + { UnitTypeId.CurrencyPerWatt, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, -1), + Tuple.Create(UnitTypeId.Meters, -2), + Tuple.Create(UnitTypeId.Seconds, 3) } ) + } } ) + }, + { SpecTypeId.Efficacy, new DerivedAttributes(IFCDerivedUnitEnum.UserDefined, "Luminous Efficacy", new Dictionary() { + { UnitTypeId.LumensPerWatt, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, -1), + Tuple.Create(UnitTypeId.Meters, -2), + Tuple.Create(UnitTypeId.Seconds, 3), + Tuple.Create(UnitTypeId.Lumens, 1) } ) + } } ) + }, + { SpecTypeId.Luminance, new DerivedAttributes(IFCDerivedUnitEnum.UserDefined, "Luminance", new Dictionary() { + { UnitTypeId.CandelasPerSquareMeter, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Meters, -2), + Tuple.Create(UnitTypeId.Candelas, 1) } ) + } } ) + }, + { SpecTypeId.ElectricalPowerDensity, new DerivedAttributes(IFCDerivedUnitEnum.UserDefined, "Electrical Power Density", new Dictionary() { + { UnitTypeId.WattsPerSquareMeter, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, 1), + Tuple.Create(UnitTypeId.Seconds, -3) } ) + } } ) + }, + { SpecTypeId.PowerPerLength, new DerivedAttributes(IFCDerivedUnitEnum.UserDefined, "Power Per Length", new Dictionary() { + { UnitTypeId.WattsPerMeter, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, 1), + Tuple.Create(UnitTypeId.Meters, 1), + Tuple.Create(UnitTypeId.Seconds, -3) } ) + } } ) + }, + { SpecTypeId.ElectricalResistivity, new DerivedAttributes(IFCDerivedUnitEnum.UserDefined, "Electrical Resistivity", new Dictionary() { + { UnitTypeId.OhmMeters, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, 1), + Tuple.Create(UnitTypeId.Meters, 3), + Tuple.Create(UnitTypeId.Seconds, -3), + Tuple.Create(UnitTypeId.Amperes, -2) } ) + } } ) + }, + { SpecTypeId.HeatCapacityPerArea, new DerivedAttributes(IFCDerivedUnitEnum.UserDefined, "Heat Capacity Per Area", new Dictionary() { + { UnitTypeId.JoulesPerSquareMeterKelvin, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, 1), + Tuple.Create(UnitTypeId.Seconds, -2), + Tuple.Create(UnitTypeId.Kelvin, -1) } ) + } } ) + }, + { SpecTypeId.ThermalGradientCoefficientForMoistureCapacity, new DerivedAttributes(IFCDerivedUnitEnum.UserDefined, "Thermal Gradient Coefficient For Moisture Capacity", new Dictionary() { + { UnitTypeId.KilogramsPerKilogramKelvin, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Kelvin, -1) } ) + } } ) + }, + { SpecTypeId.ThermalMass, new DerivedAttributes(IFCDerivedUnitEnum.UserDefined, "Thermal Mass", new Dictionary() { + { UnitTypeId.JoulesPerKelvin, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, 1), + Tuple.Create(UnitTypeId.Meters, 2), + Tuple.Create(UnitTypeId.Seconds, -2), + Tuple.Create(UnitTypeId.Kelvin, -1) } ) + } } ) + }, + { SpecTypeId.AirFlowDensity, new DerivedAttributes(IFCDerivedUnitEnum.UserDefined, "Air Flow Density", new Dictionary() { + { UnitTypeId.CubicMetersPerHourSquareMeter, new DerivedInfo(1.0 / 3600.0, true, new List>() { + Tuple.Create(UnitTypeId.Meters, 1), + Tuple.Create(UnitTypeId.Seconds, -1) } ) + } } ) + }, + { SpecTypeId.AirFlowDividedByCoolingLoad, new DerivedAttributes(IFCDerivedUnitEnum.UserDefined, "Air Flow Divided By Cooling Load", new Dictionary() { + { UnitTypeId.LitersPerSecondKilowatt, new DerivedInfo(1.0e-3 * 1.0e-3, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, -1), + Tuple.Create(UnitTypeId.Meters, 1), + Tuple.Create(UnitTypeId.Seconds, 2) } ) + } } ) + }, + { SpecTypeId.AirFlowDividedByVolume, new DerivedAttributes(IFCDerivedUnitEnum.UserDefined, "Air Flow Divided By Volume", new Dictionary() { + { UnitTypeId.CubicMetersPerHourCubicMeter, new DerivedInfo(1.0 / 3600.0, true, new List>() { + Tuple.Create(UnitTypeId.Seconds, -1) } ) + } } ) + }, + { SpecTypeId.AreaDividedByCoolingLoad, new DerivedAttributes(IFCDerivedUnitEnum.UserDefined, "Area Divided By Cooling Load", new Dictionary() { + { UnitTypeId.SquareMetersPerKilowatt, new DerivedInfo(1.0e-3, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, -1), + Tuple.Create(UnitTypeId.Seconds, 3) } ) + } } ) + }, + { SpecTypeId.AreaDividedByHeatingLoad, new DerivedAttributes(IFCDerivedUnitEnum.UserDefined, "Area Divided By Heating Load", new Dictionary() { + { UnitTypeId.SquareMetersPerKilowatt, new DerivedInfo(1.0e-3, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, -1), + Tuple.Create(UnitTypeId.Seconds, 3) } ) + } } ) + }, + { SpecTypeId.CoolingLoadDividedByArea, new DerivedAttributes(IFCDerivedUnitEnum.UserDefined, "Cooling Load Divided By Area", new Dictionary() { + { UnitTypeId.WattsPerSquareMeter, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, 1), + Tuple.Create(UnitTypeId.Seconds, -3) } ) + } } ) + }, + { SpecTypeId.CoolingLoadDividedByVolume, new DerivedAttributes(IFCDerivedUnitEnum.UserDefined, "Cooling Load Divided By Volume", new Dictionary() { + { UnitTypeId.WattsPerCubicMeter, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, 1), + Tuple.Create(UnitTypeId.Meters, -1), + Tuple.Create(UnitTypeId.Seconds, -3) } ) + } } ) + }, + { SpecTypeId.FlowPerPower, new DerivedAttributes(IFCDerivedUnitEnum.UserDefined, "Flow Per Power", new Dictionary() { + { UnitTypeId.CubicMetersPerWattSecond, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, -1), + Tuple.Create(UnitTypeId.Meters, 1), + Tuple.Create(UnitTypeId.Seconds, 2) } ) + } } ) + }, + { SpecTypeId.HvacFriction, new DerivedAttributes(IFCDerivedUnitEnum.UserDefined, "Friction Loss", new Dictionary() { + { UnitTypeId.PascalsPerMeter, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, 1), + Tuple.Create(UnitTypeId.Meters, -2), + Tuple.Create(UnitTypeId.Seconds, -2) } ) + } } ) + }, + { SpecTypeId.HeatingLoadDividedByArea, new DerivedAttributes(IFCDerivedUnitEnum.UserDefined, "Heating Load Divided By Area", new Dictionary() { + { UnitTypeId.WattsPerSquareMeter, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, 1), + Tuple.Create(UnitTypeId.Seconds, -3) } ) + } } ) + }, + { SpecTypeId.HeatingLoadDividedByVolume, new DerivedAttributes(IFCDerivedUnitEnum.UserDefined, "Heating Load Divided By Volume", new Dictionary() { + { UnitTypeId.WattsPerCubicMeter, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, 1), + Tuple.Create(UnitTypeId.Meters, -1), + Tuple.Create(UnitTypeId.Seconds, -3) } ) + } } ) + }, + { SpecTypeId.PowerPerFlow, new DerivedAttributes(IFCDerivedUnitEnum.UserDefined, "Power Per Flow", new Dictionary() { + { UnitTypeId.WattsPerCubicMeterPerSecond, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, 1), + Tuple.Create(UnitTypeId.Meters, -1), + Tuple.Create(UnitTypeId.Seconds, -2) } ) + } } ) + }, + { SpecTypeId.PipingFriction, new DerivedAttributes(IFCDerivedUnitEnum.UserDefined, "Piping Friction", new Dictionary() { + { UnitTypeId.PascalsPerMeter, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, 1), + Tuple.Create(UnitTypeId.Meters, -2), + Tuple.Create(UnitTypeId.Seconds, -2) } ) + } } ) + }, + { SpecTypeId.AreaSpringCoefficient, new DerivedAttributes(IFCDerivedUnitEnum.UserDefined, "Area Spring Coefficient", new Dictionary() { + { UnitTypeId.PascalsPerMeter, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, 1), + Tuple.Create(UnitTypeId.Meters, -2), + Tuple.Create(UnitTypeId.Seconds, -2) } ) + } } ) + }, + { SpecTypeId.LineSpringCoefficient, new DerivedAttributes(IFCDerivedUnitEnum.UserDefined, "Line Spring Coefficient", new Dictionary() { + { UnitTypeId.Pascals, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, 1), + Tuple.Create(UnitTypeId.Meters, -1), + Tuple.Create(UnitTypeId.Seconds, -2) } ) + } } ) + }, + { SpecTypeId.MassPerUnitArea, new DerivedAttributes(IFCDerivedUnitEnum.UserDefined, "Mass Per Unit Area", new Dictionary() { + { UnitTypeId.KilogramsPerSquareMeter, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, 1), + Tuple.Create(UnitTypeId.Meters, -2) } ) + } } ) + }, + { SpecTypeId.ReinforcementAreaPerUnitLength, new DerivedAttributes(IFCDerivedUnitEnum.UserDefined, "Reinforcement Area Per Unit Length", new Dictionary() { + { UnitTypeId.SquareMetersPerMeter, new DerivedInfo(null, true, new List>() { + Tuple.Create(UnitTypeId.Meters, 2), + Tuple.Create(UnitTypeId.Meters, -1) } ) + } } ) + }, + { SpecTypeId.RotationalLineSpringCoefficient, new DerivedAttributes(IFCDerivedUnitEnum.UserDefined, "Rotational Line Spring Coefficient", new Dictionary() { + { UnitTypeId.KilonewtonMetersPerDegreePerMeter, new DerivedInfo(1.0e+3 * 180.0 / Math.PI, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, 1), + Tuple.Create(UnitTypeId.Meters, 1), + Tuple.Create(UnitTypeId.Seconds, -2), + Tuple.Create(UnitTypeId.Radians, -1) } ) + } } ) + }, + { SpecTypeId.RotationalPointSpringCoefficient, new DerivedAttributes(IFCDerivedUnitEnum.UserDefined, "Rotational Point Spring Coefficient", new Dictionary() { + { UnitTypeId.KilonewtonMetersPerDegree, new DerivedInfo(1.0e+3 * 180.0 / Math.PI, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, 1), + Tuple.Create(UnitTypeId.Meters, 2), + Tuple.Create(UnitTypeId.Seconds, -2), + Tuple.Create(UnitTypeId.Radians, -1) } ) + } } ) + }, + { SpecTypeId.UnitWeight, new DerivedAttributes(IFCDerivedUnitEnum.UserDefined, "Unit Weight", new Dictionary() { + { UnitTypeId.KilonewtonsPerCubicMeter, new DerivedInfo(1.0e+3, true, new List>() { + Tuple.Create(UnitTypeId.Kilograms, 1), + Tuple.Create(UnitTypeId.Meters, -2), + Tuple.Create(UnitTypeId.Seconds, -2) } ) + } } ) + } + }; + + /// + /// The dictionary contains specific unit name mapping for ExportAsCOBIE + /// + private static readonly Dictionary CobieUnitNameMapping = new Dictionary() + { + { "SQUARE INCH", "inch" }, + { "SQUARE FOOT", "foot" }, + { "CUBIC INCH", "inch" }, + { "CUBIC FOOT", "foot" } + }; + + /// + /// The dictionary contains Ifc to Revit data type mapping + /// + private static readonly Dictionary IfcToRevitDataTypeMapping = new Dictionary() + { + { "IfcAccelerationMeasure", SpecTypeId.Acceleration }, + { "IfcAngularVelocityMeasure", SpecTypeId.Pulsation }, + { "IfcAreaDensityMeasure", SpecTypeId.MassPerUnitArea }, + { "IfcAreaMeasure", SpecTypeId.Area }, + { "IfcDynamicViscosityMeasure", SpecTypeId.HvacViscosity }, + { "IfcElectricCurrentMeasure", SpecTypeId.Current }, + { "IfcElectricVoltageMeasure", SpecTypeId.ElectricalPotential }, + { "IfcEnergyMeasure", SpecTypeId.Energy }, + { "IfcForceMeasure", SpecTypeId.Force }, + { "IfcFrequencyMeasure", SpecTypeId.ElectricalFrequency }, + { "IfcHeatFluxDensityMeasure", SpecTypeId.HvacPowerDensity }, + { "IfcHeatingValueMeasure", SpecTypeId.SpecificHeatOfVaporization }, + { "IfcIlluminanceMeasure", SpecTypeId.Illuminance }, + { "IfcIonConcentrationMeasure", SpecTypeId.PipingDensity }, + { "IfcIsothermalMoistureCapacityMeasure", SpecTypeId.IsothermalMoistureCapacity }, + { "IfcLengthMeasure", SpecTypeId.Length }, + { "IfcLinearForceMeasure", SpecTypeId.LinearForce }, + { "IfcLinearMomentMeasure", SpecTypeId.LinearMoment }, + { "IfcLinearStiffnessMeasure", SpecTypeId.PointSpringCoefficient }, + { "IfcLinearVelocityMeasure", SpecTypeId.HvacVelocity }, + { "IfcLuminousFluxMeasure", SpecTypeId.LuminousFlux }, + { "IfcLuminousIntensityMeasure", SpecTypeId.LuminousIntensity }, + { "IfcMassDensityMeasure", SpecTypeId.MassDensity }, + { "IfcMassFlowRateMeasure", SpecTypeId.PipingMassPerTime }, + { "IfcMassMeasure", SpecTypeId.Mass }, + { "IfcMassPerLengthMeasure", SpecTypeId.MassPerUnitLength }, + { "IfcModulusOfElasticityMeasure", SpecTypeId.Stress }, + { "IfcMoistureDiffusivityMeasure", SpecTypeId.Diffusivity }, + { "IfcMomentOfInertiaMeasure", SpecTypeId.MomentOfInertia }, + { "IfcPlanarForceMeasure", SpecTypeId.AreaForce }, + { "IfcPlaneAngleMeasure", SpecTypeId.Angle }, + { "IfcPositiveLengthMeasure", SpecTypeId.Length }, + { "IfcPositivePlaneAngleMeasure", SpecTypeId.Angle }, + { "IfcPowerMeasure", SpecTypeId.HvacPower }, + { "IfcPressureMeasure", SpecTypeId.HvacPressure }, + { "IfcRotationalFrequencyMeasure", SpecTypeId.AngularSpeed }, + { "IfcSoundPowerMeasure", SpecTypeId.Wattage }, + { "IfcSoundPressureMeasure", SpecTypeId.HvacPressure }, + { "IfcSpecificHeatCapacityMeasure", SpecTypeId.SpecificHeat }, + { "IfcThermalConductivityMeasure", SpecTypeId.ThermalConductivity }, + { "IfcThermalExpansionCoefficientMeasure", SpecTypeId.ThermalExpansionCoefficient }, + { "IfcThermalResistanceMeasure", SpecTypeId.ThermalResistance }, + { "IfcThermalTransmittanceMeasure", SpecTypeId.HeatTransferCoefficient }, + { "IfcThermodynamicTemperatureMeasure", SpecTypeId.HvacTemperature }, + { "IfcTimeMeasure", SpecTypeId.Time }, + { "IfcTorqueMeasure", SpecTypeId.Moment }, + { "IfcVolumeMeasure", SpecTypeId.Volume }, + { "IfcVolumetricFlowRateMeasure", SpecTypeId.AirFlow }, + { "IfcWarpingConstantMeasure", SpecTypeId.WarpingConstant }, + }; + #endregion + + } +} diff --git a/Source/Revit.IFC.Export/Utility/UnitUtil.cs b/Source/Revit.IFC.Export/Utility/UnitUtil.cs index 818d4279..0436fb57 100644 --- a/Source/Revit.IFC.Export/Utility/UnitUtil.cs +++ b/Source/Revit.IFC.Export/Utility/UnitUtil.cs @@ -29,7 +29,7 @@ namespace Revit.IFC.Export.Utility { /// - /// Utilities to work with ExporterCacheManager.UnitCache. + /// Utilities to work with ExporterCacheManager.UnitsCache. /// public class UnitUtil { @@ -365,6 +365,26 @@ static public double ScaleMassDensity(double unscaledValue) return ScaleDouble(SpecTypeId.MassDensity, unscaledValue); } + /// + /// Converts Mass in Revit internal units to Revit display units. + /// + /// The Mass in Revit internal units. + /// The Mass in Revit display units. + static public double ScaleMass(double unscaledValue) + { + return ScaleDouble(SpecTypeId.Mass, unscaledValue); + } + + /// + /// Converts LinearVelocity in Revit internal units to Revit display units. + /// + /// The LinearVelocity in Revit internal units. + /// The LinearVelocity in Revit display units. + static public double ScaleLinearVelocity(double unscaledValue) + { + return ScaleDouble(SpecTypeId.HvacVelocity, unscaledValue); + } + /// /// Converts ModulusOfElasticity in Revit internal units to Revit display units. /// @@ -495,6 +515,26 @@ static public double ScaleThermalConductivity(double unscaledValue) return ScaleDouble(SpecTypeId.ThermalConductivity, unscaledValue); } + /// + /// Converts RotationalFrequency in Revit internal units to Revit display units. + /// + /// The RotationalFrequency in Revit internal units. + /// The RotationalFrequency in Revit display units. + static public double ScaleRotationalFrequency(double unscaledValue) + { + return ScaleDouble(SpecTypeId.AngularSpeed, unscaledValue); + } + + /// + /// Converts ScaleMassFlowRate in Revit internal units to Revit display units. + /// + /// The ScaleMassFlowRate in Revit internal units. + /// The ScaleMassFlowRate in Revit display units. + static public double ScaleMassFlowRate(double unscaledValue) + { + return ScaleDouble(SpecTypeId.PipingMassPerTime, unscaledValue); + } + /// /// Converts a position in IFC units to Revit internal units. /// diff --git a/Source/Revit.IFC.Export/Utility/UnitsCache.cs b/Source/Revit.IFC.Export/Utility/UnitsCache.cs index 41292ab7..f7125d39 100644 --- a/Source/Revit.IFC.Export/Utility/UnitsCache.cs +++ b/Source/Revit.IFC.Export/Utility/UnitsCache.cs @@ -23,101 +23,215 @@ using System.Text; using Autodesk.Revit.DB; using Autodesk.Revit.DB.IFC; +using Revit.IFC.Common.Utility; using Revit.IFC.Export.Exporter; using Revit.IFC.Export.Toolkit; namespace Revit.IFC.Export.Utility { + /// + /// The class contains information about created and mapped unit. + /// + public class UnitInfo + { + public UnitInfo(IFCAnyHandle handle, double scaleFactor, double offset) + { + Handle = handle; + ScaleFactor = scaleFactor; + Offset = offset; + } + + public IFCAnyHandle Handle { get; private set; } = null; + public double ScaleFactor { get; private set; } = 1.0; + public double Offset { get; private set; } = 0.0; + } + + /// /// Used to keep a cache of the created IfcUnits. /// public class UnitsCache : Dictionary { - Dictionary> m_UnitConversionTable = - new Dictionary>(); + /// + /// The dictionary mapping from Revit data type (SpecTypeId) + /// to created ifc unit handle with convesion values (scale and offset). + /// + Dictionary m_unitInfoTable = + new Dictionary(); + + /// + /// The dictionary mapping from Revit unit (UnitTypeId) to created ifc handle. + /// These are the auxiliary unit handles that don't go to IfcUnitAssignment + /// + Dictionary m_auxiliaryUnitCache = + new Dictionary(); + + /// + /// The dictionary mapping from a unit handle with exponent to IfcDerivedUnitElement handle. + /// + Dictionary, IFCAnyHandle> m_derivedUnitElementCache = + new Dictionary, IFCAnyHandle>(); + + /// + /// Finds UnitInfo in dictionary + /// + public bool FindUnitInfo(ForgeTypeId specTypeId, out UnitInfo unitInfo) + { + return m_unitInfoTable.TryGetValue(specTypeId, out unitInfo); + } + + /// + /// Adds UnitInfo to dictionary + /// + public void RegisterUnitInfo(ForgeTypeId specTypeId, UnitInfo unitInfo) + { + m_unitInfoTable[specTypeId] = unitInfo; + } + /// + /// Extracts the unit handles to assign to a project + /// + /// Unit handles set + public HashSet GetUnitsToAssign() + { + HashSet unitSet = new HashSet(); + foreach (var unitInfo in m_unitInfoTable) + { + // Special case: SpecTypeId.ColorTemperature is mapped to SI IFCUnit.ThermoDynamicTemperatureUnit (Kelvin) + // and mustn't be assigned to project to avoid conflict with ThermoDynamicTemperatureUnit of SpecTypeId.HvacTemperature + if (unitInfo.Key.Equals(SpecTypeId.ColorTemperature)) + continue; + + IFCAnyHandle unitHnd = unitInfo.Value?.Handle; + if (unitHnd != null) + unitSet.Add(unitHnd); + } + return unitSet; + } + + + /// + /// Finds auxiliary unit in dictionary + /// + public bool FindAuxiliaryUnit(ForgeTypeId unitTypeId, out IFCAnyHandle auxiliaryUnit) + { + return m_auxiliaryUnitCache.TryGetValue(unitTypeId, out auxiliaryUnit); + } + + /// + /// Adds auxiliary unit to dictionary + /// + public void RegisterAuxiliaryUnit(ForgeTypeId unitTypeId, IFCAnyHandle auxiliaryUnit) + { + m_auxiliaryUnitCache[unitTypeId] = auxiliaryUnit; + } + + /// + /// Finds derived unit element in dictionary + /// + public bool FindDerivedUnitElement(Tuple unitWithExponent, out IFCAnyHandle derivedUnit) + { + return m_derivedUnitElementCache.TryGetValue(unitWithExponent, out derivedUnit); + } + + /// + /// Adds derived unit element to dictionary + /// + public void RegisterDerivedUnit(Tuple unitWithExponent, IFCAnyHandle derivedUnit) + { + m_derivedUnitElementCache[unitWithExponent] = derivedUnit; + } + + /// + /// Finds user defined unit in dictionary + /// + public IFCAnyHandle FindUserDefinedUnit(string unitName) + { + return this.ContainsKey(unitName) ? this[unitName] : null; + } + + /// + /// Adds user defined unit to dictionary + /// + public void RegisterUserDefinedUnit(string unitName, IFCAnyHandle unitHnd) + { + this[unitName] = unitHnd; + } + + #region Scale/unscale methods /// /// Convert from Revit internal units to Revit display units. /// - /// Identifier of the spec. + /// Revit data type /// The value in Revit internal units. /// The value in Revit display units. public double Scale(ForgeTypeId specTypeId, double unscaledValue) { - Tuple scale; - if (m_UnitConversionTable.TryGetValue(specTypeId, out scale)) - return unscaledValue * scale.Item2 + scale.Item3; + UnitInfo unitInfo = UnitMappingUtil.GetOrCreateUnitInfo(specTypeId); + if (unitInfo != null) + return unscaledValue * unitInfo.ScaleFactor + unitInfo.Offset; return unscaledValue; } /// /// Convert from Revit display units to Revit internal units. /// - /// Identifier of the spec. - /// The value in Revit display units. + /// Revit data type + /// The value in Revit display units. /// The value in Revit internal units. /// Ignores the offset component. public XYZ Unscale(ForgeTypeId specTypeId, XYZ scaledValue) { - Tuple scale; - if (m_UnitConversionTable.TryGetValue(specTypeId, out scale)) - return scaledValue / scale.Item2; + UnitInfo unitInfo = UnitMappingUtil.GetOrCreateUnitInfo(specTypeId); + if (unitInfo != null) + return scaledValue / unitInfo.ScaleFactor; return scaledValue; } /// /// Convert from Revit display units to Revit internal units. /// - /// Identifier of the spec. + /// Revit data type /// The value in Revit display units. /// The value in Revit internal units. public double Unscale(ForgeTypeId specTypeId, double scaledValue) { - Tuple scale; - if (m_UnitConversionTable.TryGetValue(specTypeId, out scale)) - return (scaledValue - scale.Item3) / scale.Item2; + UnitInfo unitInfo = UnitMappingUtil.GetOrCreateUnitInfo(specTypeId); + if (unitInfo != null) + return (scaledValue - unitInfo.Offset) / unitInfo.ScaleFactor; return scaledValue; } /// /// Convert from Revit internal units to Revit display units. /// - /// Identifier of the spec. + /// Revit data type /// The value in Revit internal units. /// The value in Revit display units. /// Ignores the offset component. public UV Scale(ForgeTypeId specTypeId, UV unscaledValue) { - Tuple scale; - if (m_UnitConversionTable.TryGetValue(specTypeId, out scale)) - return unscaledValue * scale.Item2; + UnitInfo unitInfo = UnitMappingUtil.GetOrCreateUnitInfo(specTypeId); + if (unitInfo != null) + return unscaledValue * unitInfo.ScaleFactor; return unscaledValue; } /// /// Convert from Revit internal units to Revit display units. /// - /// Identifier of the spec. + /// Revit data type /// The value in Revit internal units. /// The value in Revit display units. /// Ignores the offset component. public XYZ Scale(ForgeTypeId specTypeId, XYZ unscaledValue) { - Tuple scale; - if (m_UnitConversionTable.TryGetValue(specTypeId, out scale)) - return unscaledValue * scale.Item2; + UnitInfo unitInfo = UnitMappingUtil.GetOrCreateUnitInfo(specTypeId); + if (unitInfo != null) + return unscaledValue * unitInfo.ScaleFactor; return unscaledValue; } - - /// - /// Sets the conversion factors to convert Revit internal units to Revit display units for the specified unit type, and stores the IFC handle. - /// - /// Identifier of the spec. - /// The IFCUnit handle. - /// The scaling factor. - public void AddUnit(ForgeTypeId specTypeId, IFCAnyHandle unitHandle, double scale, double offset) - { - m_UnitConversionTable[specTypeId] = new Tuple(unitHandle, scale, offset); - } + #endregion } + } \ No newline at end of file diff --git a/Source/Revit.IFC.Import.Core/Properties/AssemblyInfo.cs b/Source/Revit.IFC.Import.Core/Properties/AssemblyInfo.cs index 3fea00a5..959c17f2 100644 --- a/Source/Revit.IFC.Import.Core/Properties/AssemblyInfo.cs +++ b/Source/Revit.IFC.Import.Core/Properties/AssemblyInfo.cs @@ -12,9 +12,9 @@ [assembly: AssemblyTitle("Revit.IFC.Import.Core")] [assembly: AssemblyDescription("Revit.IFC.Import.Core")] [assembly: AssemblyCompany("Autodesk")] -[assembly: AssemblyCopyright("@2012-2023 Autodesk, Inc. All rights reserved.")] -[assembly: AssemblyVersion("24.2.0.49")] -[assembly: AssemblyFileVersion("24.2.0.49")] +[assembly: AssemblyCopyright("@2012-2024 Autodesk, Inc. All rights reserved.")] +[assembly: AssemblyVersion("25.2.0.5")] +[assembly: AssemblyFileVersion("25.2.0.5")] // Version information can now be found in Source\Foundation\RevitENU\Version.cs // diff --git a/Source/Revit.IFC.Import.Core/Revit.IFC.Import.Core.csproj b/Source/Revit.IFC.Import.Core/Revit.IFC.Import.Core.csproj index d975ca71..2f14f119 100644 --- a/Source/Revit.IFC.Import.Core/Revit.IFC.Import.Core.csproj +++ b/Source/Revit.IFC.Import.Core/Revit.IFC.Import.Core.csproj @@ -1,64 +1,16 @@ - - - + - Debug - x64 - {B1E159B7-4B12-45A9-B83F-159E37798D44} - Library - Properties Revit.IFC.Import.Core Revit.IFC.Import.Core - v4.8 - 512 - true - - - prompt - x64 - - - prompt - x64 - bin\Releasex64\ - - - prompt - x64 - bin\Debugx64\ + + + + - ..\..\..\..\Program Files\Autodesk\Revit 2024\RevitAPI.dll + ..\..\..\..\Program Files\Autodesk\Revit 2025\RevitAPI.dll - - - - - - - - - - - - - - - - - xcopy "$(TargetPath)" "C:\ProgramData\Autodesk\ApplicationPlugins\IFC 2024.bundle\Contents\2024\" /F /R /Y /I - - - \ No newline at end of file + + diff --git a/Source/Revit.IFC.Import.Core/Revit.IFC.Import.Core.props b/Source/Revit.IFC.Import.Core/Revit.IFC.Import.Core.props deleted file mode 100644 index daf0f829..00000000 --- a/Source/Revit.IFC.Import.Core/Revit.IFC.Import.Core.props +++ /dev/null @@ -1,25 +0,0 @@ - - - - bin\Debugx64\ - DEBUG;TRACE;IFC_OPENSOURCE - true - false - false - 4 - full - prompt - - - bin\Releasex64\ - TRACE;IFC_OPENSOURCE - false - true - false - 4 - none - prompt - - - - diff --git a/Source/Revit.IFC.Import/Data/IFCBlock.cs b/Source/Revit.IFC.Import/Data/IFCBlock.cs index 61d46dcb..ebaaa28e 100644 --- a/Source/Revit.IFC.Import/Data/IFCBlock.cs +++ b/Source/Revit.IFC.Import/Data/IFCBlock.cs @@ -81,10 +81,10 @@ protected IFCBlock() { block = GeometryCreationUtilities.CreateExtrusionGeometry(loops, scaledExtrusionDirection, ZLength, solidOptions); } - catch (Exception ex) + catch (Exception) { if (shapeEditScope.MustCreateSolid()) - throw ex; + throw; Importer.TheLog.LogError(Id, "Block has an invalid definition for a solid; reverting to mesh.", false); diff --git a/Source/Revit.IFC.Import/Data/IFCBooleanOperand.cs b/Source/Revit.IFC.Import/Data/IFCBooleanOperand.cs index 6a27af74..8c5981af 100644 --- a/Source/Revit.IFC.Import/Data/IFCBooleanOperand.cs +++ b/Source/Revit.IFC.Import/Data/IFCBooleanOperand.cs @@ -34,29 +34,14 @@ public static IIFCBooleanOperand ProcessIFCBooleanOperand(IFCAnyHandle ifcBoolea return null; } - // If Hybrid IFC Import is in progress, make sure that the correct RepresentationItem is created. - if (Importer.TheOptions.IsHybridImport && (Importer.TheHybridInfo?.RepresentationsAlreadyCreated ?? false)) - { - // Check for Subtypes that Legacy Import would otherwise process. - if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcBooleanOperand, IFCEntityType.IfcBooleanResult) || - IFCAnyHandleUtil.IsValidSubTypeOf(ifcBooleanOperand, IFCEntityType.IfcHalfSpaceSolid) || - IFCAnyHandleUtil.IsValidSubTypeOf(ifcBooleanOperand, IFCEntityType.IfcSolidModel) || - IFCAnyHandleUtil.IsValidSubTypeOf(ifcBooleanOperand, IFCEntityType.IfcCsgPrimitive3D)) - { - return IFCHybridRepresentationItem.ProcessIFCHybridRepresentationItem(ifcBooleanOperand); - } - } - else - { - if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcBooleanOperand, IFCEntityType.IfcBooleanResult)) - return IFCBooleanResult.ProcessIFCBooleanResult(ifcBooleanOperand); - else if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcBooleanOperand, IFCEntityType.IfcHalfSpaceSolid)) - return IFCHalfSpaceSolid.ProcessIFCHalfSpaceSolid(ifcBooleanOperand); - else if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcBooleanOperand, IFCEntityType.IfcSolidModel)) - return IFCSolidModel.ProcessIFCSolidModel(ifcBooleanOperand); - else if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcBooleanOperand, IFCEntityType.IfcCsgPrimitive3D)) - return IFCCsgPrimitive3D.ProcessIFCCsgPrimitive3D(ifcBooleanOperand); - } + if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcBooleanOperand, IFCEntityType.IfcBooleanResult)) + return IFCBooleanResult.ProcessIFCBooleanResult(ifcBooleanOperand); + if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcBooleanOperand, IFCEntityType.IfcHalfSpaceSolid)) + return IFCHalfSpaceSolid.ProcessIFCHalfSpaceSolid(ifcBooleanOperand); + else if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcBooleanOperand, IFCEntityType.IfcSolidModel)) + return IFCSolidModel.ProcessIFCSolidModel(ifcBooleanOperand); + else if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcBooleanOperand, IFCEntityType.IfcCsgPrimitive3D)) + return IFCCsgPrimitive3D.ProcessIFCCsgPrimitive3D(ifcBooleanOperand); Importer.TheLog.LogUnhandledSubTypeError(ifcBooleanOperand, "IfcBooleanOperand", true); return null; diff --git a/Source/Revit.IFC.Import/Data/IFCBooleanResult.cs b/Source/Revit.IFC.Import/Data/IFCBooleanResult.cs index 012be545..8b670254 100644 --- a/Source/Revit.IFC.Import/Data/IFCBooleanResult.cs +++ b/Source/Revit.IFC.Import/Data/IFCBooleanResult.cs @@ -172,7 +172,7 @@ private IFCStyledItem GetStyledItemFromOperand(IFCRepresentationItem repItem) if (SecondOperand is IFCRepresentationItem) Importer.TheLog.LogError((SecondOperand as IFCRepresentationItem).Id, ex.Message, false); else - throw ex; + throw; secondSolids = null; } } diff --git a/Source/Revit.IFC.Import/Data/IFCBuildingElementProxy.cs b/Source/Revit.IFC.Import/Data/IFCBuildingElementProxy.cs index 3a8354f7..b7b75912 100644 --- a/Source/Revit.IFC.Import/Data/IFCBuildingElementProxy.cs +++ b/Source/Revit.IFC.Import/Data/IFCBuildingElementProxy.cs @@ -136,7 +136,7 @@ protected override void Create(Document doc) IList clonedGeometry = CloneElementGeometry(doc, this, this, false); foreach (IFCSolidInfo solid in clonedGeometry) { - if (CutSolidByVoids(solid)) + if (CutSolidByVoids(solid, null)) geomObjs.Add(solid.GeometryObject); } diff --git a/Source/Revit.IFC.Import/Data/IFCBuildingStorey.cs b/Source/Revit.IFC.Import/Data/IFCBuildingStorey.cs index 1bdaad36..9a06b8e5 100644 --- a/Source/Revit.IFC.Import/Data/IFCBuildingStorey.cs +++ b/Source/Revit.IFC.Import/Data/IFCBuildingStorey.cs @@ -135,7 +135,7 @@ protected override void Create(Document doc) foundLevel = true; double referenceElevation = GetReferenceElevation(); - double totalElevation = (ObjectLocation?.TotalTransform?.Origin.Z ?? 0.0) + referenceElevation; + double totalElevation = (ObjectLocation?.TotalTransformAfterOffset?.Origin.Z ?? 0.0) + referenceElevation; if (level == null) level = Level.Create(doc, totalElevation); diff --git a/Source/Revit.IFC.Import/Data/IFCConnectedFaceSet.cs b/Source/Revit.IFC.Import/Data/IFCConnectedFaceSet.cs index cc447718..b75fbb20 100644 --- a/Source/Revit.IFC.Import/Data/IFCConnectedFaceSet.cs +++ b/Source/Revit.IFC.Import/Data/IFCConnectedFaceSet.cs @@ -71,7 +71,7 @@ override protected void Process(IFCAnyHandle ifcConnectedFaceSet) HashSet ifcCfsFaces = IFCAnyHandleUtil.GetValidAggregateInstanceAttribute>(ifcConnectedFaceSet, "CfsFaces"); - if (ifcCfsFaces?.Count == 0) + if ((ifcCfsFaces?.Count ?? 0) == 0) { Importer.TheLog.LogError(ifcConnectedFaceSet.StepId, "No faces in connected face set, aborting.", false); return; @@ -115,7 +115,7 @@ override protected void Process(IFCAnyHandle ifcConnectedFaceSet) catch (Exception ex) { if (!AllowInvalidFace) - throw ex; + throw; else { shapeEditScope.BuilderScope.AbortCurrentFace(); diff --git a/Source/Revit.IFC.Import/Data/IFCDistributionPort.cs b/Source/Revit.IFC.Import/Data/IFCDistributionPort.cs index e55bcc8a..82ede0f7 100644 --- a/Source/Revit.IFC.Import/Data/IFCDistributionPort.cs +++ b/Source/Revit.IFC.Import/Data/IFCDistributionPort.cs @@ -106,9 +106,16 @@ protected override void Create(Document doc) lcs = ContainedIn?.ObjectLocation?.TotalTransform; } + if (lcs == null) + { lcs = Transform.Identity; + } + // We could use ObjectLocation?.TotalTransformAfterOffset above, but that is + // slightly different behavior, since TotalTransformAfterOffset is never null. + lcs.Origin += (Importer.TheHybridInfo?.LargeCoordinateOriginOffset ?? XYZ.Zero); + // 2016+ only. XYZ origin = lcs.Origin; diff --git a/Source/Revit.IFC.Import/Data/IFCElement.cs b/Source/Revit.IFC.Import/Data/IFCElement.cs index 1a67c0b0..f7ea2fb6 100644 --- a/Source/Revit.IFC.Import/Data/IFCElement.cs +++ b/Source/Revit.IFC.Import/Data/IFCElement.cs @@ -89,13 +89,6 @@ public IFCFeatureElementSubtraction FillsOpening set { m_FillsOpening = value; } } - /// - /// IfcElements are allowed to serve as Containers whose DirectShapes will contain - /// Geometry from other DirectShapes. - /// - /// True. This will always be true for IfcElements. - public override bool IsAllowedToAggregateGeometry() => true; - /// /// Default constructor. /// diff --git a/Source/Revit.IFC.Import/Data/IFCExtrudedAreaSolid.cs b/Source/Revit.IFC.Import/Data/IFCExtrudedAreaSolid.cs index 9766b91a..050c0e67 100644 --- a/Source/Revit.IFC.Import/Data/IFCExtrudedAreaSolid.cs +++ b/Source/Revit.IFC.Import/Data/IFCExtrudedAreaSolid.cs @@ -828,12 +828,12 @@ private IList GetOrientedCurveList(IList loops, Curve axisCurv extrusionObject = GeometryCreationUtilities.CreateExtrusionGeometry(loops, scaledExtrusionDirection, currDepth, solidOptions); } } - catch (Exception ex) + catch (Exception) { extrusionObject = GetMeshBackup(shapeEditScope, loops, scaledExtrusionDirection, currDepth, guid); if (extrusionObject == null) - throw ex; + throw; } if (extrusionObject != null) diff --git a/Source/Revit.IFC.Import/Data/IFCGrid.cs b/Source/Revit.IFC.Import/Data/IFCGrid.cs index 6e2c6cf2..b33677e9 100644 --- a/Source/Revit.IFC.Import/Data/IFCGrid.cs +++ b/Source/Revit.IFC.Import/Data/IFCGrid.cs @@ -499,7 +499,7 @@ public override string GetSharedParameterName(IFCSharedParameters name, bool isT /// The document. protected override void Create(Document doc) { - Transform lcs = (ObjectLocation != null) ? ObjectLocation.TotalTransform : Transform.Identity; + Transform lcs = (ObjectLocation != null) ? ObjectLocation.TotalTransformAfterOffset : Transform.Identity; CreateOneDirection(UAxes, doc, lcs); CreateOneDirection(VAxes, doc, lcs); diff --git a/Source/Revit.IFC.Import/Data/IFCGridAxis.cs b/Source/Revit.IFC.Import/Data/IFCGridAxis.cs index 48061052..ebc18f8b 100644 --- a/Source/Revit.IFC.Import/Data/IFCGridAxis.cs +++ b/Source/Revit.IFC.Import/Data/IFCGridAxis.cs @@ -340,7 +340,7 @@ public Curve GetAxisCurveForGridPlacement() if (ParentGrid != null && ParentGrid.ObjectLocation != null) { - Transform lcs = ParentGrid.ObjectLocation.TotalTransform; + Transform lcs = ParentGrid.ObjectLocation.TotalTransformAfterOffset; axisCurve = axisCurve.CreateTransformed(lcs); } diff --git a/Source/Revit.IFC.Import/Data/IFCHybridRepresentationItem.cs b/Source/Revit.IFC.Import/Data/IFCHybridRepresentationItem.cs deleted file mode 100644 index ea1f5870..00000000 --- a/Source/Revit.IFC.Import/Data/IFCHybridRepresentationItem.cs +++ /dev/null @@ -1,112 +0,0 @@ -// -// Revit IFC Import library: this library works with Autodesk(R) Revit(R) to import IFC files. -// Copyright (C) 2013 Autodesk, Inc. -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Autodesk.Revit.DB; -using Autodesk.Revit.DB.IFC; -using Revit.IFC.Common.Utility; -using Revit.IFC.Common.Enums; -using Revit.IFC.Import.Geometry; -using Revit.IFC.Import.Utility; - -namespace Revit.IFC.Import.Data -{ - // For Hybrid IFC Import, Revit needs something to represent Body Geometry other than null. - // Body geometry for DirectShapes are actually created by AnyCAD, but there are other data within a RepresentationItem - // that must persist. - // IFCHybridRepresentationItem must inherit from IIFCBooleanOperand, since it may need to represent an operand, which (in essence) - // has already been created. - public class IFCHybridRepresentationItem : IFCRepresentationItem, IIFCBooleanOperand - { - protected IFCHybridRepresentationItem() - { - } - - /// - /// Constructor to create a new IFCHybridRepresentationItem. - /// - /// Handle representing IFCRepresentationItem. - protected IFCHybridRepresentationItem(IFCAnyHandle ifcRepresentationItem) - { - Process(ifcRepresentationItem); - } - - /// - /// Process IFCHybridRepresentationItem members. - /// Even though we don't have any members, it exists to maintain a parallel structure of other IFCEntity processing. - /// - /// Handle representing IFCRepresentationItem. - override protected void Process(IFCAnyHandle ifcRepresentationItem) - { - base.Process(ifcRepresentationItem); - } - - /// - /// Create the IFCHybridRepresentationItem. - /// - /// Handle corresponding to the IFCRepresentationItem that AnyCAD already processed. - /// IFCHybridRepresentationItem object. - public static IFCHybridRepresentationItem ProcessIFCHybridRepresentationItem(IFCAnyHandle ifcRepresentationItem) - { - if (IFCAnyHandleUtil.IsNullOrHasNoValue(ifcRepresentationItem)) - { - Importer.TheLog.LogNullError(IFCEntityType.IfcRepresentationItem); - return null; - } - - IFCEntity hybridRepresentationItem; - IFCImportFile.TheFile.EntityMap.TryGetValue(ifcRepresentationItem.StepId, out hybridRepresentationItem); - if (hybridRepresentationItem != null) - return (hybridRepresentationItem as IFCHybridRepresentationItem); - - return new IFCHybridRepresentationItem(ifcRepresentationItem); - } - - /// - /// Return geometry for a particular representation item. - /// In the case of Hybrid, Geometry has already been created, so only process the IfcStyledItem. - /// - /// The geometry creation scope. - /// Local coordinate system for the geometry, including scale, potentially non-uniform. - /// The guid of an element for which represntation is being created. - /// Zero or more created Solids. - public IList CreateGeometry(IFCImportShapeEditScope shapeEditScope, Transform scaledLcs, string guid) - { - if (StyledByItem != null) - StyledByItem.Create(shapeEditScope); - - return null; - } - - /// - /// In case of a Boolean operation failure, provide a recommended direction to shift the geometry in for a second attempt. - /// - /// The local transform for this entity. - /// An XYZ representing a unit direction vector, or null if no direction is suggested. - /// If the 2nd attempt fails, a third attempt will be done with a shift in the opposite direction. - public XYZ GetSuggestedShiftDirection(Transform lcs) - { - return null; - } - - } -} diff --git a/Source/Revit.IFC.Import/Data/IFCImportFile.cs b/Source/Revit.IFC.Import/Data/IFCImportFile.cs index dcccf5ba..8f018a3c 100644 --- a/Source/Revit.IFC.Import/Data/IFCImportFile.cs +++ b/Source/Revit.IFC.Import/Data/IFCImportFile.cs @@ -890,10 +890,10 @@ public static ElementId LinkInFile(string originalIFCFileName, string baseLocalF Importer.PostDelayedLinkErrors(originalDocument); linkTransaction.Commit(); } - catch (Exception ex) + catch (Exception) { linkTransaction.RollBack(); - throw ex; + throw; } } else // reload from @@ -1151,9 +1151,12 @@ static IFCFileModelOptions GetIFCFileModelOptions(string schemaName, out IFCSche } else if (schemaName.Equals("IFC4X3", StringComparison.OrdinalIgnoreCase)) { - //schemaVersion = IFCSchemaVersion.IFC4x3; schemaVersion = IFCSchemaVersion.IFC4x3; } + else if (schemaName.Equals("IFC4X3_ADD2", StringComparison.OrdinalIgnoreCase)) + { + schemaVersion = IFCSchemaVersion.IFC4x3_ADD2; + } else throw new ArgumentException("Invalid or unsupported schema: " + schemaName); diff --git a/Source/Revit.IFC.Import/Data/IFCIndexedPolyCurve.cs b/Source/Revit.IFC.Import/Data/IFCIndexedPolyCurve.cs index 09a2754d..909bcc56 100644 --- a/Source/Revit.IFC.Import/Data/IFCIndexedPolyCurve.cs +++ b/Source/Revit.IFC.Import/Data/IFCIndexedPolyCurve.cs @@ -108,7 +108,7 @@ protected override void Process(IFCAnyHandle ifcCurve) if (IFCImportFile.HasUndefinedAttribute(ex)) IFCImportFile.TheFile.DowngradeIFC4SchemaTo(IFCSchemaVersion.IFC4); else - throw ex; + throw; } IFCCartesianPointList pointList = IFCCartesianPointList.ProcessIFCCartesianPointList(points); diff --git a/Source/Revit.IFC.Import/Data/IFCLocation.cs b/Source/Revit.IFC.Import/Data/IFCLocation.cs index f4f11cb0..1dae731e 100644 --- a/Source/Revit.IFC.Import/Data/IFCLocation.cs +++ b/Source/Revit.IFC.Import/Data/IFCLocation.cs @@ -45,6 +45,19 @@ public Transform TotalTransform get { return RelativeTo != null ? RelativeTo.TotalTransform.Multiply(RelativeTransform) : RelativeTransform; } } + /// + /// The total transform, taking into account any large coordinate offset. + /// + public Transform TotalTransformAfterOffset + { + get + { + Transform totalTransform = TotalTransform ?? Transform.Identity; + totalTransform.Origin += (Importer.TheHybridInfo?.LargeCoordinateOriginOffset ?? XYZ.Zero); + return totalTransform; + } + } + /// /// The relative transform. /// @@ -295,7 +308,7 @@ public static IFCLocation ProcessIFCObjectPlacement(IFCAnyHandle ifcObjectPlacem public static void WarnIfFaraway(IFCProduct product) { - XYZ origin = product?.ObjectLocation?.TotalTransform?.Origin; + XYZ origin = product?.ObjectLocation?.TotalTransformAfterOffset?.Origin; if (origin != null && !XYZ.IsWithinLengthLimits(origin)) { Importer.TheLog.LogWarning(product.Id, "This entity has an origin that is outside of Revit's creation limits. This could result in bad graphical display of geometry.", false); diff --git a/Source/Revit.IFC.Import/Data/IFCMappedItem.cs b/Source/Revit.IFC.Import/Data/IFCMappedItem.cs index eec928ea..24605deb 100644 --- a/Source/Revit.IFC.Import/Data/IFCMappedItem.cs +++ b/Source/Revit.IFC.Import/Data/IFCMappedItem.cs @@ -68,8 +68,6 @@ override protected void Process(IFCAnyHandle item) return; MappingSource = IFCRepresentationMap.ProcessIFCRepresentationMap(mappingSource); - if (MappingSource.IsHybridOnly()) - return; // We will not fail if the transform is not given, but instead assume it to be the identity. IFCAnyHandle mappingTarget = IFCImportHandleUtil.GetRequiredInstanceAttribute(item, "MappingTarget", false); diff --git a/Source/Revit.IFC.Import/Data/IFCMaterial.cs b/Source/Revit.IFC.Import/Data/IFCMaterial.cs index c8762f61..f77325ff 100644 --- a/Source/Revit.IFC.Import/Data/IFCMaterial.cs +++ b/Source/Revit.IFC.Import/Data/IFCMaterial.cs @@ -83,16 +83,19 @@ protected override void Process(IFCAnyHandle ifcMaterial) Name = IFCImportHandleUtil.GetRequiredStringAttribute(ifcMaterial, "Name", true); - List hasRepresentation = null; - if (IFCImportFile.TheFile.SchemaVersionAtLeast(IFCSchemaVersion.IFC2x3)) - hasRepresentation = IFCAnyHandleUtil.GetAggregateInstanceAttribute>(ifcMaterial, "HasRepresentation"); - - if ((hasRepresentation?.Count ?? 0) == 1) + if (!Importer.TheOptions.IsHybridImport) { - if (!IFCAnyHandleUtil.IsSubTypeOf(hasRepresentation[0], IFCEntityType.IfcMaterialDefinitionRepresentation)) - Importer.TheLog.LogUnexpectedTypeError(hasRepresentation[0], IFCEntityType.IfcMaterialDefinitionRepresentation, false); - else - MaterialDefinitionRepresentation = IFCProductRepresentation.ProcessIFCProductRepresentation(hasRepresentation[0]); + List hasRepresentation = null; + if (IFCImportFile.TheFile.SchemaVersionAtLeast(IFCSchemaVersion.IFC2x3)) + hasRepresentation = IFCAnyHandleUtil.GetAggregateInstanceAttribute>(ifcMaterial, "HasRepresentation"); + + if ((hasRepresentation?.Count ?? 0) == 1) + { + if (!IFCAnyHandleUtil.IsSubTypeOf(hasRepresentation[0], IFCEntityType.IfcMaterialDefinitionRepresentation)) + Importer.TheLog.LogUnexpectedTypeError(hasRepresentation[0], IFCEntityType.IfcMaterialDefinitionRepresentation, false); + else + MaterialDefinitionRepresentation = IFCProductRepresentation.ProcessIFCProductRepresentation(hasRepresentation[0]); + } } Importer.TheLog.AddToElementCount(); diff --git a/Source/Revit.IFC.Import/Data/IFCObject.cs b/Source/Revit.IFC.Import/Data/IFCObject.cs index d6b0ce2c..d58f9d56 100644 --- a/Source/Revit.IFC.Import/Data/IFCObject.cs +++ b/Source/Revit.IFC.Import/Data/IFCObject.cs @@ -212,26 +212,27 @@ protected override void Process(IFCAnyHandle ifcObject) else if (IFCAnyHandleUtil.IsSubTypeOf(isDefinedByHandle, IFCEntityType.IfcRelDefinesByType)) { // For Hybrid IFC Import, preprocess IFCRelDefinesByType. - // Need to do this because the TypeObject should have a GlobalId --> DirectShapeType before Revit calls ProcessIFCTypeObject. - // This will add an entry to the HybridMap (IFCTypeObject GlobalId --> DirectShapeType ElementId) so Revit will know later that it doesn't need + // Need to do this because the TypeObject should have a STEP Id --> DirectShapeType before Revit calls ProcessIFCTypeObject. + // This will add an entry to the HybridMap (IFCTypeObject STEP Id --> DirectShapeType ElementId) so Revit will know later that it doesn't need // to create a new DirectShapeType, and which DirectShapeType to use. - if (Importer.TheOptions.IsHybridImport && (Importer.TheHybridInfo?.HybridMap?.ContainsKey(GlobalId) ?? false)) + ElementId ifcObjectElementId = IFCImportHybridInfo.GetHybridMapInformation(ifcObject); + if (IFCImportHybridInfo.IsValidElementId(ifcObjectElementId)) { IFCAnyHandle typeObject = IFCAnyHandleUtil.GetInstanceAttribute(isDefinedByHandle, "RelatingType"); - if (IFCAnyHandleUtil.IsNullOrHasNoValue(typeObject)) { Importer.TheLog.LogNullError(IFCEntityType.IfcTypeObject); + return; } if (!IFCAnyHandleUtil.IsSubTypeOf(typeObject, IFCEntityType.IfcTypeObject)) { Importer.TheLog.LogUnhandledSubTypeError(typeObject, IFCEntityType.IfcTypeObject, false); + return; } - Importer.TheHybridInfo.AddTypeToHybridMap(GlobalId, typeObject); + Importer.TheHybridInfo.AddTypeToHybridMap(ifcObjectElementId, typeObject); } - ProcessIFCRelDefinesByType(isDefinedByHandle); } else diff --git a/Source/Revit.IFC.Import/Data/IFCObjectDefinition.cs b/Source/Revit.IFC.Import/Data/IFCObjectDefinition.cs index ecb3ee2b..64e6d047 100644 --- a/Source/Revit.IFC.Import/Data/IFCObjectDefinition.cs +++ b/Source/Revit.IFC.Import/Data/IFCObjectDefinition.cs @@ -1,4 +1,4 @@ -// +// // Revit IFC Import library: this library works with Autodesk(R) Revit(R) to import IFC files. // Copyright (C) 2013 Autodesk, Inc. // @@ -120,31 +120,6 @@ public virtual bool GroupSubElements() /// public IFCObjectDefinition Decomposes { get; set; } = null; - /// - /// Indicates if this IFCObjectDefinition is allowed to act as a Container whose DirectShape will have Geometry that will contain - /// Geometry from DirectShapes corresponding to other entities. - /// This is defined via an IfcRelAggregates relationship, but it only applies if the "RelatedTo" entity will result in a DirectShape - /// in the Revit Document. - /// This is used to indicate that this entity can act in this capacity. - /// - /// False unless overridden by a derived class. - public virtual bool IsAllowedToAggregateGeometry() => false; - - /// - /// Indicates if this IfcObjectDefinition is acting as a Container whose DirectShape will have Geometry that will contain - /// Geometry from DirectShapes corresponding to other entities. - /// This only applies to Hybrid Import. - /// This is used to indicate that this actually is acting in this capacity. - /// - /// - public bool IsHybridImportContainer() - { - return Importer.TheOptions.IsHybridImport && - IsAllowedToAggregateGeometry() && - ((ComposedObjectDefinitions?.Count ?? 0) > 0) && - (Importer.TheHybridInfo?.ContainerMap?.ContainsKey(Id) ?? false); - } - /// /// Get the reference elevation of this object, located in the containing IFCBuilding. /// @@ -415,7 +390,7 @@ private IList GetOrCloneGeometry(Document doc, IFCObjectDefiniti foreach (IFCSolidInfo solid in clonedGeometry) { - if (CutSolidByVoids(solid)) + if (CutSolidByVoids(solid, null)) geomObjs.Add(solid.GeometryObject); } @@ -426,9 +401,10 @@ private IList GetOrCloneGeometry(Document doc, IFCObjectDefiniti /// Cut a IFCSolidInfo by the voids in this IFCProduct, if any. /// /// The solid information. + /// Extra voids from AnyCAD-created openings. /// False if the return solid is empty; true otherwise. /// Overridden at the IFCProduct level. - protected virtual bool CutSolidByVoids(IFCSolidInfo solidInfo) + protected virtual bool CutSolidByVoids(IFCSolidInfo solidInfo, IList createdVoids) { return true; } @@ -555,9 +531,10 @@ protected override void Process(IFCAnyHandle ifcObjectDefinition) PredefinedType = GetPredefinedType(ifcObjectDefinition); ElementId createdElementId = ElementId.InvalidElementId; - if (Importer.TheOptions.IsHybridImport) + ElementId objectDefinitionElementId = IFCImportHybridInfo.GetHybridMapInformation(Id); + if (objectDefinitionElementId != null) { - Importer.TheHybridInfo?.HybridMap?.TryGetValue(GlobalId, out createdElementId); + createdElementId = objectDefinitionElementId; } // If we aren't importing this category, skip processing. diff --git a/Source/Revit.IFC.Import/Data/IFCProduct.cs b/Source/Revit.IFC.Import/Data/IFCProduct.cs index 326d2785..04fd428a 100644 --- a/Source/Revit.IFC.Import/Data/IFCProduct.cs +++ b/Source/Revit.IFC.Import/Data/IFCProduct.cs @@ -1,4 +1,4 @@ -// +// // Revit IFC Import library: this library works with Autodesk(R) Revit(R) to import IFC files. // Copyright (C) 2013 Autodesk, Inc. // @@ -109,13 +109,16 @@ protected override void Process(IFCAnyHandle ifcProduct) base.Process(ifcProduct); + // Don't even process IfcProductRepresentation if this IfcProduct was imported via Hybrid import. + if (IFCImportHybridInfo.IsValidElementId(IFCImportHybridInfo.GetHybridMapInformation(Id))) + { + return; + } + IFCAnyHandle ifcProductRepresentation = IFCImportHandleUtil.GetOptionalInstanceAttribute(ifcProduct, "Representation"); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(ifcProductRepresentation)) { - using (RepresentationsAlreadyCreatedSetter setter = new RepresentationsAlreadyCreatedSetter(GlobalId)) - { - ProductRepresentation = IFCProductRepresentation.ProcessIFCProductRepresentation(ifcProductRepresentation); - } + ProductRepresentation = IFCProductRepresentation.ProcessIFCProductRepresentation(ifcProductRepresentation); } } @@ -194,16 +197,25 @@ protected override void CreateParametersInternal(Document doc, Element element) /// Private function to determine whether an IFCProduct directly contains valid geometry. /// /// - /// For Hybrid IFC Import, ProductRepresentation should still exist and be valid. + /// For Hybrid IFC Import, ProductRepresentation may not exist, but Geometry is instead within a GeometryInstance. /// /// True if the IFCProduct directly contains valid geometry. private bool HasValidTopLevelGeometry() { + // If this IfcProduct was imported via Hybrid import, ProductRepresentation may not exist. Check for DirectShape instead. + ElementId directShapeId = IFCImportHybridInfo.GetHybridMapInformation(Id); + if (IFCImportHybridInfo.IsValidElementId(directShapeId)) + { + // Or continue the check and require that the directShapeId point to + // a DirectShape (not DirectShapeType) -- unsure! + return Importer.TheHybridInfo.IsValidDirectShape(directShapeId); + } + return (ProductRepresentation != null && ProductRepresentation.IsValid()); } /// - /// Private function to determine whether an IFCProduct contins geometry in a sub-element. + /// Private function to determine whether an IFCProduct contains geometry in a sub-element. /// /// A list of already visited entities, to avoid infinite recursion. /// True if the IFCProduct directly or indirectly contains geometry. @@ -233,8 +245,9 @@ private bool HasValidSubElementGeometry(IList visitedEntities) /// Cut a IFCSolidInfo by the voids in this IFCProduct, if any. /// /// The solid information. + /// Extra voids from AnyCAD-created openings. /// False if the return solid is empty; true otherwise. - protected override bool CutSolidByVoids(IFCSolidInfo solidInfo) + protected override bool CutSolidByVoids(IFCSolidInfo solidInfo, IList createdVoids) { // We only cut "Body" representation items. if (solidInfo.RepresentationIdentifier != IFCRepresentationIdentifier.Body) @@ -267,16 +280,38 @@ protected override bool CutSolidByVoids(IFCSolidInfo solidInfo) return true; } + List> allVoids = new List>(); + + if (createdVoids != null) + { + foreach (Solid createdVoid in createdVoids) + { + if (createdVoid != null) + { + allVoids.Add(Tuple.Create(createdVoid, null, -1)); + } + } + } + foreach (IFCVoidInfo voidInfo in voidsToUse) { Solid voidObject = voidInfo.GeometryObject as Solid; + int voidId = voidInfo.Id; if (voidObject == null) { - Importer.TheLog.LogError(Id, "Can't cut Solid geometry with a Mesh (# " + voidInfo.Id + "), ignoring.", false); + Importer.TheLog.LogError(Id, "Can't cut Solid geometry with a Mesh (# " + voidId + "), ignoring.", false); continue; } Transform voidTransform = voidInfo.TotalTransform; + allVoids.Add(Tuple.Create(voidObject, voidTransform, voidId)); + } + + foreach (Tuple currentVoid in allVoids) + { + Solid voidObject = currentVoid.Item1; + Transform voidTransform = currentVoid.Item2; + int voidId = currentVoid.Item3; if (voidTransform != null) { @@ -288,7 +323,7 @@ protected override bool CutSolidByVoids(IFCSolidInfo solidInfo) } } - solidInfo.GeometryObject = IFCGeometryUtil.ExecuteSafeBooleanOperation(solidInfo.Id, voidInfo.Id, + solidInfo.GeometryObject = IFCGeometryUtil.ExecuteSafeBooleanOperation(solidInfo.Id, voidId, (solidInfo.GeometryObject as Solid), voidObject, BooleanOperationsType.Difference, null); if (solidInfo.GeometryObject == null || (solidInfo.GeometryObject as Solid).Faces.IsEmpty) @@ -303,13 +338,36 @@ private Transform CalculateLocalCoordinateSystem() Transform lcs = IFCImportFile.TheFile.IFCProject.WorldCoordinateSystem; if (lcs == null) return ObjectLocation?.TotalTransform ?? Transform.Identity; - + if (ObjectLocation != null) return lcs.Multiply(ObjectLocation.TotalTransform); return lcs; } + private IList GetCreatedGeometries(Document doc, IFCProduct opening, Options geometryOptions) + { + ElementId createdOpeningId = IFCImportHybridInfo.GetHybridMapInformation(opening.Id); + if (IFCImportHybridInfo.IsValidElementId(createdOpeningId)) + { + DirectShape openingElement = doc.GetElement(createdOpeningId) as DirectShape; + if (openingElement != null) + { + GeometryElement geometryElement = openingElement.get_Geometry(geometryOptions); + + SolidMeshGeometryInfo solidInfo = new SolidMeshGeometryInfo(); + solidInfo.CollectSolidMeshGeometry(geometryElement, Importer.TheCache.AllocatedGeometryObjectCache); + return solidInfo.GetSolids(); + } + else + { + Importer.TheLog.LogError(Id, "Object created in legacy mode missing opening information.", false); + } + } + + return null; + } + /// /// Creates or populates Revit elements based on the information contained in this class. /// @@ -318,13 +376,24 @@ protected override void Create(Document doc) { bool preventInstances = false; IFCElement element = this as IFCElement; + List createdVoids = new List(); + if (element != null) { preventInstances = this is IFCOpeningElement; + + Options geometryOptions = new Options(); + foreach (IFCFeatureElement opening in element.Openings) { try { + IList createdGeometries = GetCreatedGeometries(doc, opening, geometryOptions); + if (createdGeometries != null) + { + createdVoids.AddRange(createdGeometries); + } + preventInstances = true; // Create the actual Revit element based on the IFCFeatureElement here. ElementId openingId = CreateElement(doc, opening); @@ -359,7 +428,7 @@ protected override void Create(Document doc) // If this entity will be a container DirectShape, it may not have any valid top-level geometry at this time. // Detect the situation and allow Element Creation to proceed for Hybrid Import only. - if (HasValidTopLevelGeometry() || IsHybridImportContainer()) + if (HasValidTopLevelGeometry()) { // IFCImportShapeEditScope will not create Body geometry for Hybrid IFC Import, but it may need to create other geometry. using (IFCImportShapeEditScope shapeEditScope = IFCImportShapeEditScope.Create(doc, this)) @@ -367,58 +436,33 @@ protected override void Create(Document doc) Transform lcs = CalculateLocalCoordinateSystem(); shapeEditScope.PreventInstances = preventInstances; - - // Hybrid Import only: An IfcProduct whose DirectShape will be a container might not have a DirectShape created yet. - // If this is the case, create an empty DirectShape for the container. - // If so, create an empty DirectShape to hold container Geometry. - if (Importer.TheOptions.IsHybridImport && (Importer.TheHybridInfo?.HybridMap != null)) - { - if (IsHybridImportContainer() && !Importer.TheHybridInfo.HybridMap.ContainsKey(GlobalId)) - { - CreatedElementId = Importer.TheHybridInfo.CreateEmptyContainer(this); - Importer.TheLog.LogComment(Id, $"Creating Empty Container for {GlobalId}:{CreatedElementId}", false); - } - } - if (HasValidTopLevelGeometry()) + // If we are not applying transforms to the geometry, then pass in the identity matrix. + // Lower down this method we then pass lcs to the consumer element, so that it can apply + // the transform as required. + Transform transformToUse = Importer.TheProcessor.ApplyTransforms ? lcs : Transform.Identity; + bool applyHybridOffset = Importer.TheOptions.IsHybridImport && Importer.TheHybridInfo != null && ObjectLocation?.RelativeTo == null; + if (applyHybridOffset) { - // If we are not applying transforms to the geometry, then pass in the identity matrix. - // Lower down this method we then pass lcs to the consumer element, so that it can apply - // the transform as required. - Transform transformToUse = Importer.TheProcessor.ApplyTransforms ? lcs : Transform.Identity; - if (Importer.TheOptions.IsHybridImport && ( - Importer.TheHybridInfo != null)) - { - transformToUse.Origin += Importer.TheHybridInfo.LargeCoordinateOriginOffset; - } - - // The name can be added as well. but it is usually less useful than 'oid' - string myId = GlobalId; // + "(" + Name + ")"; - - ProductRepresentation.CreateProductRepresentation(shapeEditScope, transformToUse, myId); + transformToUse.Origin += Importer.TheHybridInfo.LargeCoordinateOriginOffset; } - // Everything up to this point needs to be done for Hybrid IFC Import as well. The Product Representation will not contain - // geometry, but it will contain parameters that are needed for the DirectShape imported for Hybrid IFC Import. - if (Importer.TheOptions.IsHybridImport && GlobalId != null) + // If Revit has already created a DirectShape from the IfcProduct, don't try and create a new representation. + ElementId hybridDirectShapeElementId = IFCImportHybridInfo.GetHybridMapInformation(Id); + if (IFCImportHybridInfo.IsValidElementId(hybridDirectShapeElementId)) { - if ((Importer.TheHybridInfo?.HybridMap?.TryGetValue(GlobalId, out ElementId hybridElementId) ?? false) && - hybridElementId != ElementId.InvalidElementId) - { - // "Create" a DirectShape Element. - // This is for those Elements imported via the ATF Pipeline, or for those Elements created above simply to hold an empty container. - CreatedGeometry = Importer.TheHybridInfo.HandleHybridProductCreation(shapeEditScope, this, ref hybridElementId); - CreatedElementId = hybridElementId; - } + CreatedGeometry = Importer.TheHybridInfo.HandleHybridProductCreation(this, hybridDirectShapeElementId); + CreatedElementId = hybridDirectShapeElementId; } + else + { + ProductRepresentation.CreateProductRepresentation(shapeEditScope, transformToUse, GlobalId); - if (CreatedElementId == ElementId.InvalidElementId) - { int numSolids = Solids.Count; // Attempt to cut each solid with each void. for (int solidIdx = 0; solidIdx < numSolids; solidIdx++) { - if (!CutSolidByVoids(Solids[solidIdx])) + if (!CutSolidByVoids(Solids[solidIdx], createdVoids)) { Solids.RemoveAt(solidIdx); solidIdx--; @@ -446,19 +490,19 @@ protected override void Create(Document doc) { // We need to check if the solid created is good enough for DirectShape. If not, warn and use a fallback Mesh. GeometryObject currObject = geometryObject.GeometryObject; - if (currObject is Solid) + + if (currObject != null) { - Solid solid = currObject as Solid; - if (!shape.IsValidGeometry(solid)) + IList adjustedObjects = IFCGeometryUtil.AdjustGeometryObjectsIfNeeded(currObject, shape, Id); + if (adjustedObjects != null) { - Importer.TheLog.LogWarning(Id, "Couldn't create valid solid, reverting to mesh.", false); - directShapeGeometries.AddRange(IFCGeometryUtil.CreateMeshesFromSolid(solid)); - currObject = null; + directShapeGeometries.AddRange(adjustedObjects); + } + else + { + directShapeGeometries.Add(currObject); } } - - if (currObject != null) - directShapeGeometries.Add(currObject); } // We will use the first IfcTypeObject id, if it exists. In general, there should be 0 or 1. @@ -546,9 +590,6 @@ public static IFCProduct ProcessIFCProduct(IFCAnyHandle ifcProduct) if (IFCImportFile.TheFile.EntityMap.TryGetValue(ifcProduct.StepId, out cachedProduct)) return (cachedProduct as IFCProduct); - if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcProduct, IFCEntityType.IfcSpatialStructureElement)) - return IFCSpatialStructureElement.ProcessIFCSpatialStructureElement(ifcProduct); - if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcProduct, IFCEntityType.IfcElement)) return IFCElement.ProcessIFCElement(ifcProduct); @@ -563,6 +604,17 @@ public static IFCProduct ProcessIFCProduct(IFCAnyHandle ifcProduct) if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcProduct, IFCEntityType.IfcAnnotation)) return IFCAnnotation.ProcessIFCAnnotation(ifcProduct); + + if (IFCImportFile.TheFile.SchemaVersionAtLeast(Enums.IFCSchemaVersion.IFC4Obsolete)) + { + if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcProduct, IFCEntityType.IfcSpatialElement)) + return IFCSpatialElement.ProcessIFCSpatialElement(ifcProduct); + } + else + { + if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcProduct, IFCEntityType.IfcSpatialStructureElement)) + return IFCSpatialStructureElement.ProcessIFCSpatialStructureElement(ifcProduct); + } } catch (Exception ex) { diff --git a/Source/Revit.IFC.Import/Data/IFCProfileDef.cs b/Source/Revit.IFC.Import/Data/IFCProfileDef.cs index 6ebf3e81..50f6a1a6 100644 --- a/Source/Revit.IFC.Import/Data/IFCProfileDef.cs +++ b/Source/Revit.IFC.Import/Data/IFCProfileDef.cs @@ -98,7 +98,7 @@ protected bool AppendSegmentsToCurveLoop(CurveLoop curveLoop, IList /// Processes IfcProject attributes. /// @@ -257,13 +276,11 @@ protected override void Process(IFCAnyHandle ifcProjectHandle) } ProjectLocation projectLocation = IFCImportFile.TheFile.Document.ActiveProjectLocation; - ProjectPosition projectPosition; if (projectLocation != null) { if (hasMapConv) { - projectPosition = new ProjectPosition(geoRef.X, geoRef.Y, geoRef.Z, trueNorth); - projectLocation.SetProjectPosition(XYZ.Zero, projectPosition); + UpdateProjectLocation(projectLocation, geoRef, trueNorth); if (!string.IsNullOrEmpty(geoRefName)) { @@ -313,8 +330,7 @@ protected override void Process(IFCAnyHandle ifcProjectHandle) } } - projectPosition = new ProjectPosition(geoRef.X, geoRef.Y, geoRef.Z, trueNorth); - projectLocation.SetProjectPosition(XYZ.Zero, projectPosition); + UpdateProjectLocation(projectLocation, geoRef, trueNorth); } } } diff --git a/Source/Revit.IFC.Import/Data/IFCRepresentation.cs b/Source/Revit.IFC.Import/Data/IFCRepresentation.cs index 78541c92..9a1e3cc6 100644 --- a/Source/Revit.IFC.Import/Data/IFCRepresentation.cs +++ b/Source/Revit.IFC.Import/Data/IFCRepresentation.cs @@ -21,13 +21,17 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Windows.Annotations; +using System.Windows; using Autodesk.Revit.DB; using Autodesk.Revit.DB.IFC; +using Microsoft.VisualBasic.Logging; using Revit.IFC.Common.Enums; using Revit.IFC.Common.Utility; using Revit.IFC.Import.Enums; using Revit.IFC.Import.Geometry; using Revit.IFC.Import.Utility; +using static System.Windows.Forms.VisualStyles.VisualStyleElement.Tab; namespace Revit.IFC.Import.Data { @@ -74,28 +78,21 @@ protected IFCRepresentation() } - /// - /// Determine if the IFCRepresentationMap only has at least 1 IFCHybridInformation. - /// - /// True if the IFCRepresentationMap only has at least 1 IFCHybridInformation. - public bool IsHybridOnly() - { - if ((RepresentationItems?.Count ?? 0) == 0) - return false; - - foreach (IFCRepresentationItem item in RepresentationItems) - { - if (!(item is IFCHybridRepresentationItem)) - return false; - } - - return true; - } - - private IFCRepresentationIdentifier GetRepresentationIdentifier(string identifier, IFCAnyHandle ifcRepresentation) + private IFCRepresentationIdentifier GetRepresentationIdentifier(string identifier, string type, IFCAnyHandle ifcRepresentation) { if (Enum.TryParse(identifier, true, out IFCRepresentationIdentifier ifcRepresentationIdentifier)) { + // Special case for Annotation. + switch (ifcRepresentationIdentifier) + { + case IFCRepresentationIdentifier.Annotation: + if (string.Compare(type, "Annotation2D", true) == 0) + { + return IFCRepresentationIdentifier.FootPrint; + } + return IFCRepresentationIdentifier.Body; + } + return ifcRepresentationIdentifier; } @@ -104,19 +101,31 @@ private IFCRepresentationIdentifier GetRepresentationIdentifier(string identifie // NOTE: This list includes invalid or obsolete identifiers found in real IFC files. if ((string.Compare(identifier, "Facetation", true) == 0) || string.IsNullOrWhiteSpace(identifier)) + { return IFCRepresentationIdentifier.Body; + } + if (string.Compare(identifier, "BoundingBox", true) == 0) + { return IFCRepresentationIdentifier.Box; - if ((string.Compare(identifier, "Annotation", true) == 0) || - (string.Compare(identifier, "Profile", true) == 0) || - (string.Compare(identifier, "Plan", true) == 0)) + } + + if (string.Compare(identifier, "Plan", true) == 0) + { return IFCRepresentationIdentifier.FootPrint; + } + if (IFCAnyHandleUtil.IsSubTypeOf(ifcRepresentation, IFCEntityType.IfcStyledRepresentation)) + { return IFCRepresentationIdentifier.Style; + } + if (string.Compare(identifier, "Body-Fallback", true) == 0) + { return IFCRepresentationIdentifier.BodyFallback; + } - Importer.TheLog.LogWarning(ifcRepresentation.StepId, "Found unknown representation type: " + identifier, false); + Importer.TheLog.LogWarning(ifcRepresentation.StepId, "Found unknown representation identifier: " + identifier, false); return IFCRepresentationIdentifier.Other; } @@ -158,7 +167,10 @@ override protected void Process(IFCAnyHandle ifcRepresentation) base.Process(ifcRepresentation); string identifier = IFCImportHandleUtil.GetOptionalStringAttribute(ifcRepresentation, "RepresentationIdentifier", null); - Identifier = GetRepresentationIdentifier(identifier, ifcRepresentation); + + string type = IFCImportHandleUtil.GetOptionalStringAttribute(ifcRepresentation, "RepresentationType", null); + + Identifier = GetRepresentationIdentifier(identifier, type, ifcRepresentation); LayerAssignment = IFCPresentationLayerAssignment.GetTheLayerAssignment(ifcRepresentation); @@ -184,12 +196,17 @@ override protected void Process(IFCAnyHandle ifcRepresentation) continue; } - // Special processing for bounding boxes - only IfcBoundingBox allowed. if (IFCAnyHandleUtil.IsSubTypeOf(item, IFCEntityType.IfcBoundingBox)) { - // Don't read in Box represenation unless options allow it. + // If Hybrid/Non-legacy, don't process BoundingBox. + if (Importer.TheOptions.IsHybridImport) + continue; + + // Don't read in Box representation unless options allow it. if (IFCImportFile.TheFile.Options.ProcessBoundingBoxGeometry == IFCProcessBBoxOptions.Never) + { Importer.TheLog.LogWarning(item.StepId, "BoundingBox not imported with ProcessBoundingBoxGeometry=Never", false); + } else { if (BoundingBox != null) @@ -201,7 +218,9 @@ override protected void Process(IFCAnyHandle ifcRepresentation) } } else + { repItem = IFCRepresentationItem.ProcessIFCRepresentationItem(item); + } } catch (Exception ex) { @@ -213,10 +232,6 @@ override protected void Process(IFCAnyHandle ifcRepresentation) } } - // If we have a body representation and we have already gone through Hybrid, skip the rest of the work here. - if (Identifier == IFCRepresentationIdentifier.Body && (Importer.TheHybridInfo?.RepresentationsAlreadyCreated ?? false)) - return; - IFCAnyHandle representationContext = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcRepresentation, "ContextOfItems", false); if (representationContext != null) Context = IFCRepresentationContext.ProcessIFCRepresentationContext(representationContext); @@ -265,7 +280,7 @@ private void CreateBoxShape(IFCImportShapeEditScope shapeEditScope, Transform sc /// /// The geometry creation scope. /// Local coordinate system for the geometry, including scale, potentially non-uniform. - /// The guid of an element for which represntation is being created. + /// The guid of an element for which representation is being created. public void CreateShape(IFCImportShapeEditScope shapeEditScope, Transform scaledLcs, string guid) { // Special handling for Box representation. We may decide to create an IFCBoundingBox class and stop this special treatment. diff --git a/Source/Revit.IFC.Import/Data/IFCRepresentationItem.cs b/Source/Revit.IFC.Import/Data/IFCRepresentationItem.cs index 14ed537a..9750c067 100644 --- a/Source/Revit.IFC.Import/Data/IFCRepresentationItem.cs +++ b/Source/Revit.IFC.Import/Data/IFCRepresentationItem.cs @@ -72,10 +72,6 @@ override protected void Process(IFCAnyHandle item) LayerAssignment = IFCPresentationLayerAssignment.GetTheLayerAssignment(item); - // Don't bother processing styled items we will never use. - if (this is IFCHybridRepresentationItem) - return; - // IFC2x has a different representation for styled items which we don't support. ICollection styledByItems = null; if (Importer.TheCache.StyledByItems.TryGetValue(item, out styledByItems)) @@ -159,66 +155,58 @@ public static IFCRepresentationItem ProcessIFCRepresentationItem(IFCAnyHandle if return null; } - // Skip Body Geometry if doing Hybrid IFC Import and currently processing Hybrid IfcProductRepresentation. - bool skipBodyGeometry = (Importer.TheOptions.IsHybridImport) && (Importer.TheHybridInfo?.RepresentationsAlreadyCreated ?? false); - if (!skipBodyGeometry) + // Legacy. + if (IFCAnyHandleUtil.IsSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcTopologicalRepresentationItem)) + return IFCTopologicalRepresentationItem.ProcessIFCTopologicalRepresentationItem(ifcRepresentationItem); + + // TODO: Move everything below to IFCGeometricRepresentationItem, once it is created. + if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcFaceBasedSurfaceModel)) + return IFCFaceBasedSurfaceModel.ProcessIFCFaceBasedSurfaceModel(ifcRepresentationItem); + if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcShellBasedSurfaceModel)) + return IFCShellBasedSurfaceModel.ProcessIFCShellBasedSurfaceModel(ifcRepresentationItem); + if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcSolidModel)) + return IFCSolidModel.ProcessIFCSolidModel(ifcRepresentationItem); + if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcCsgPrimitive3D)) + return IFCCsgPrimitive3D.ProcessIFCCsgPrimitive3D(ifcRepresentationItem); + + // TODO: Move the items below to IFCGeometricRepresentationItem->IFCTessellatedItem->IfcTessellatedFaceSet. + if (IFCImportFile.TheFile.SchemaVersionAtLeast(IFCSchemaVersion.IFC4Obsolete) && IFCAnyHandleUtil.IsSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcTriangulatedFaceSet)) + return IFCTriangulatedFaceSet.ProcessIFCTriangulatedFaceSet(ifcRepresentationItem); + // There is no way to actually determine an IFC4Add2 file vs. a "vanilla" IFC4 file, which is + // obsolete. The try/catch here allows us to read these obsolete files without crashing. + try { - if (IFCAnyHandleUtil.IsSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcTopologicalRepresentationItem)) - return IFCTopologicalRepresentationItem.ProcessIFCTopologicalRepresentationItem(ifcRepresentationItem); - - // TODO: Move everything below to IFCGeometricRepresentationItem, once it is created. - if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcFaceBasedSurfaceModel)) - return IFCFaceBasedSurfaceModel.ProcessIFCFaceBasedSurfaceModel(ifcRepresentationItem); - if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcShellBasedSurfaceModel)) - return IFCShellBasedSurfaceModel.ProcessIFCShellBasedSurfaceModel(ifcRepresentationItem); - if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcSolidModel)) - return IFCSolidModel.ProcessIFCSolidModel(ifcRepresentationItem); - if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcCsgPrimitive3D)) - return IFCCsgPrimitive3D.ProcessIFCCsgPrimitive3D(ifcRepresentationItem); - - // TODO: Move the items below to IFCGeometricRepresentationItem->IFCTessellatedItem->IfcTessellatedFaceSet. - if (IFCImportFile.TheFile.SchemaVersionAtLeast(IFCSchemaVersion.IFC4Obsolete) && IFCAnyHandleUtil.IsSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcTriangulatedFaceSet)) - return IFCTriangulatedFaceSet.ProcessIFCTriangulatedFaceSet(ifcRepresentationItem); - // There is no way to actually determine an IFC4Add2 file vs. a "vanilla" IFC4 file, which is - // obsolete. The try/catch here allows us to read these obsolete files without crashing. - try - { - if (IFCImportFile.TheFile.SchemaVersionAtLeast(IFCSchemaVersion.IFC4) && IFCAnyHandleUtil.IsSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcPolygonalFaceSet)) - return IFCPolygonalFaceSet.ProcessIFCPolygonalFaceSet(ifcRepresentationItem); - } - catch (Exception ex) - { - // Once we fail once, downgrade the schema so we don't try again. - if (IFCImportFile.HasUndefinedAttribute(ex)) - IFCImportFile.TheFile.DowngradeIFC4SchemaTo(IFCSchemaVersion.IFC4Add1Obsolete); - else - throw ex; - } - - if (IFCAnyHandleUtil.IsSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcSurface)) - return IFCSurface.ProcessIFCSurface(ifcRepresentationItem); + if (IFCImportFile.TheFile.SchemaVersionAtLeast(IFCSchemaVersion.IFC4) && IFCAnyHandleUtil.IsSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcPolygonalFaceSet)) + return IFCPolygonalFaceSet.ProcessIFCPolygonalFaceSet(ifcRepresentationItem); + } + catch (Exception ex) + { + // Once we fail once, downgrade the schema so we don't try again. + if (IFCImportFile.HasUndefinedAttribute(ex)) + IFCImportFile.TheFile.DowngradeIFC4SchemaTo(IFCSchemaVersion.IFC4Add1Obsolete); + else + throw; } - // Need to process IFCBooleanResult because the individual operands should become IFCHybridRepresentationItem. + if (IFCAnyHandleUtil.IsSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcSurface)) + return IFCSurface.ProcessIFCSurface(ifcRepresentationItem); + if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcBooleanResult)) return IFCBooleanResult.ProcessIFCBooleanResult(ifcRepresentationItem); - // Handle IFCStyledItem since IFCHybridRepresentationItem may need to add Materials on import. if (IFCImportFile.TheFile.SchemaVersionAtLeast(IFCSchemaVersion.IFC2x2) && IFCAnyHandleUtil.IsSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcStyledItem)) return IFCStyledItem.ProcessIFCStyledItem(ifcRepresentationItem); if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcMappedItem)) return IFCMappedItem.ProcessIFCMappedItem(ifcRepresentationItem); + + if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcGeometricSet)) + return IFCGeometricSet.ProcessIFCGeometricSet(ifcRepresentationItem); + if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcCurve)) return IFCCurve.ProcessIFCCurve(ifcRepresentationItem); + if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcPoint)) return IFCPoint.ProcessIFCPoint(ifcRepresentationItem); - if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcGeometricSet)) - return IFCGeometricSet.ProcessIFCGeometricSet(ifcRepresentationItem); - - if (skipBodyGeometry) - { - return IFCHybridRepresentationItem.ProcessIFCHybridRepresentationItem(ifcRepresentationItem); - } // Everything else is an error. Importer.TheLog.LogUnhandledSubTypeError(ifcRepresentationItem, IFCEntityType.IfcRepresentationItem, false); diff --git a/Source/Revit.IFC.Import/Data/IFCRepresentationMap.cs b/Source/Revit.IFC.Import/Data/IFCRepresentationMap.cs index dfcc3838..e2bd8b7f 100644 --- a/Source/Revit.IFC.Import/Data/IFCRepresentationMap.cs +++ b/Source/Revit.IFC.Import/Data/IFCRepresentationMap.cs @@ -17,15 +17,11 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // -using System; using System.Collections.Generic; -using System.Linq; -using System.Text; using Autodesk.Revit.DB; using Autodesk.Revit.DB.IFC; using Revit.IFC.Common.Enums; using Revit.IFC.Common.Utility; -using Revit.IFC.Import.Enums; using Revit.IFC.Import.Geometry; using Revit.IFC.Import.Utility; @@ -93,15 +89,6 @@ protected IFCRepresentationMap(IFCAnyHandle representationMap) Process(representationMap); } - /// - /// Determine if the IFCRepresentationMap only has at least 1 IFCHybridInformation. - /// - /// True if the IFCRepresentationMap only has at least 1 IFCHybridInformation. - public bool IsHybridOnly() - { - return MappedRepresentation?.IsHybridOnly() ?? false; - } - /// /// Create geometry for a particular representation map. /// @@ -144,10 +131,23 @@ public void CreateShape(IFCImportShapeEditScope shapeEditScope, Transform scaled if ((numExistingSolids != numNewSolids) || (numExistingCurves != numNewCurves)) { - IList mappedSolids = new List(); + List mappedSolids = new List(); for (int ii = numExistingSolids; ii < numNewSolids; ii++) { - mappedSolids.Add(shapeEditScope.Creator.Solids[numExistingSolids].GeometryObject); + GeometryObject originalObject = shapeEditScope.Creator.Solids[numExistingSolids].GeometryObject; + if (originalObject != null) + { + // We only check curves, not solids, here, so we don't pass in a DirectShape. + IList processedList = IFCGeometryUtil.AdjustGeometryObjectsIfNeeded(originalObject, null, Id); + if (processedList != null) + { + mappedSolids.AddRange(processedList); + } + else + { + mappedSolids.Add(originalObject); + } + } shapeEditScope.Creator.Solids.RemoveAt(numExistingSolids); } diff --git a/Source/Revit.IFC.Import/Data/IFCSite.cs b/Source/Revit.IFC.Import/Data/IFCSite.cs index 65c3bbf6..738ba404 100644 --- a/Source/Revit.IFC.Import/Data/IFCSite.cs +++ b/Source/Revit.IFC.Import/Data/IFCSite.cs @@ -387,11 +387,19 @@ public static void ProcessSiteLocations(Document doc, IList sites) } // Register the offset by moving the Shared Coordinates away - ProjectPosition pPos = projectLocation.GetProjectPosition(XYZ.Zero); - pPos.EastWest += BaseSiteOffset.X; - pPos.NorthSouth += BaseSiteOffset.Y; - pPos.Elevation += BaseSiteOffset.Z; - projectLocation.SetProjectPosition(XYZ.Zero, pPos); + if (Importer.TheOptions.IsHybridImport) + { + // If we are in hybrid mode, we've already moved the project. Just change the large offset. + Importer.TheHybridInfo.LargeCoordinateOriginOffset += BaseSiteOffset; + } + else + { + ProjectPosition pPos = projectLocation.GetProjectPosition(XYZ.Zero); + pPos.EastWest += BaseSiteOffset.X; + pPos.NorthSouth += BaseSiteOffset.Y; + pPos.Elevation += BaseSiteOffset.Z; + projectLocation.SetProjectPosition(XYZ.Zero, pPos); + } } else { diff --git a/Source/Revit.IFC.Import/Data/IFCSpatialElement.cs b/Source/Revit.IFC.Import/Data/IFCSpatialElement.cs new file mode 100644 index 00000000..5ce4c846 --- /dev/null +++ b/Source/Revit.IFC.Import/Data/IFCSpatialElement.cs @@ -0,0 +1,86 @@ +// +// Revit IFC Import library: this library works with Autodesk(R) Revit(R) to import IFC files. +// Copyright (C) 2013 Autodesk, Inc. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// + +using Autodesk.Revit.DB.IFC; +using Revit.IFC.Common.Enums; +using Revit.IFC.Common.Utility; +using Revit.IFC.Import.Enums; + +namespace Revit.IFC.Import.Data +{ + /// + /// Represents an IFCSpatialElement. + /// + public class IFCSpatialElement : IFCProduct + { + /// + /// Constructs an IFCSpatialElement from the IfcSpatialElement handle. + /// + /// The IfcSpatialElement handle. + protected IFCSpatialElement(IFCAnyHandle ifcSpatialElement) + { + Process(ifcSpatialElement); + } + + /// + /// Default constructor. + /// + protected IFCSpatialElement() + { + + } + + /// + /// Processes IfcSpatialElement. + /// + /// The IfcSpatialElement handle. + protected override void Process(IFCAnyHandle ifcSpatialElement) + { + base.Process(ifcSpatialElement); + } + + /// + /// Processes IfcSpatialElement handle. + /// + /// The IfcSpatialElement handle. + /// The IFCSpatialElement object. + public static IFCSpatialElement ProcessIFCSpatialElement(IFCAnyHandle ifcSpatialElement) + { + if (IFCAnyHandleUtil.IsNullOrHasNoValue(ifcSpatialElement)) + { + Importer.TheLog.LogNullError(IFCEntityType.IfcSpatialElement); + return null; + } + + IFCEntity spatialElement; + if (IFCImportFile.TheFile.EntityMap.TryGetValue(ifcSpatialElement.StepId, out spatialElement)) + return (spatialElement as IFCSpatialElement); + + if (IFCAnyHandleUtil.IsSubTypeOf(ifcSpatialElement, IFCEntityType.IfcSpatialZone)) + return IFCSpatialZone.ProcessIFCSpatialZone(ifcSpatialElement); + else if (IFCAnyHandleUtil.IsSubTypeOf(ifcSpatialElement, IFCEntityType.IfcSpatialStructureElement)) + return IFCSpatialStructureElement.ProcessIFCSpatialStructureElement(ifcSpatialElement); + + Importer.TheLog.LogUnhandledSubTypeError(ifcSpatialElement, IFCEntityType.IfcProduct, false); + return null; + } + } +} + + diff --git a/Source/Revit.IFC.Import/Data/IFCSpatialStructureElement.cs b/Source/Revit.IFC.Import/Data/IFCSpatialStructureElement.cs index 5076e455..22bc9989 100644 --- a/Source/Revit.IFC.Import/Data/IFCSpatialStructureElement.cs +++ b/Source/Revit.IFC.Import/Data/IFCSpatialStructureElement.cs @@ -33,7 +33,7 @@ namespace Revit.IFC.Import.Data /// /// Represents an IfcSpatialStructureElement. /// - public class IFCSpatialStructureElement : IFCProduct + public class IFCSpatialStructureElement : IFCSpatialElement { HashSet m_IFCProducts = null; @@ -222,6 +222,12 @@ void ProcessIFCRelServicesBuildings(IFCAnyHandle ifcRelHandle) protected void TryToFixFarawayOrigin() { + // If we are using ATF, it should fix coordinate issues for us. + if (Importer.TheOptions.IsHybridImport) + { + return; + } + if (!(ProjectScope?.IsSet ?? false)) return; diff --git a/Source/Revit.IFC.Import/Data/IFCSpatialZone.cs b/Source/Revit.IFC.Import/Data/IFCSpatialZone.cs new file mode 100644 index 00000000..dd648543 --- /dev/null +++ b/Source/Revit.IFC.Import/Data/IFCSpatialZone.cs @@ -0,0 +1,79 @@ +// +// Revit IFC Import library: this library works with Autodesk(R) Revit(R) to import IFC files. +// Copyright (C) 2013 Autodesk, Inc. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// + +using Autodesk.Revit.DB.IFC; +using Revit.IFC.Common.Enums; +using Revit.IFC.Common.Utility; + +namespace Revit.IFC.Import.Data +{ + /// + /// Represents an IFCSpatialZone. + /// + public class IFCSpatialZone : IFCSpatialElement + { + /// + /// Constructs an IFCSpatialZone from the IfcSpatialZone handle. + /// + /// The IfcSpatialZone handle. + protected IFCSpatialZone(IFCAnyHandle ifcSpatialZone) + { + Process(ifcSpatialZone); + } + + /// + /// Default constructor. + /// + protected IFCSpatialZone() + { + + } + + /// + /// Processes IfcSpatialZone. + /// + /// The IfcSpatialZone handle. + protected override void Process(IFCAnyHandle ifcSpatialZone) + { + base.Process(ifcSpatialZone); + } + + /// + /// Processes IfcSpatialZone handle. + /// + /// The IfcSpatialZone handle. + /// The IFCSpatialZone object. + public static IFCSpatialZone ProcessIFCSpatialZone(IFCAnyHandle ifcSpatialZone) + { + if (IFCAnyHandleUtil.IsNullOrHasNoValue(ifcSpatialZone)) + { + Importer.TheLog.LogNullError(IFCEntityType.IfcSpatialZone); + return null; + } + + IFCEntity spatialZone; + if (IFCImportFile.TheFile.EntityMap.TryGetValue(ifcSpatialZone.StepId, out spatialZone)) + return (spatialZone as IFCSpatialZone); + + return new IFCSpatialZone(ifcSpatialZone); + } + } +} + + diff --git a/Source/Revit.IFC.Import/Data/IFCStyledItem.cs b/Source/Revit.IFC.Import/Data/IFCStyledItem.cs index 3098fcbf..daadd2ba 100644 --- a/Source/Revit.IFC.Import/Data/IFCStyledItem.cs +++ b/Source/Revit.IFC.Import/Data/IFCStyledItem.cs @@ -190,11 +190,6 @@ public IFCSurfaceStyle GetSurfaceStyle() /// The document. public void Create(IFCImportShapeEditScope shapeEditScope) { - // If we have an IFCHybridRepresentationItem, there's no reason to create the styled item, because - // we won't use it. - if (Item is IFCHybridRepresentationItem) - return; - // TODO: support cut pattern id and cut pattern color. if (m_CreatedElementId != ElementId.InvalidElementId || !IsValidForCreation) return; diff --git a/Source/Revit.IFC.Import/Data/IFCSweptDiskSolid.cs b/Source/Revit.IFC.Import/Data/IFCSweptDiskSolid.cs index 3f10fdf7..6110ce44 100644 --- a/Source/Revit.IFC.Import/Data/IFCSweptDiskSolid.cs +++ b/Source/Revit.IFC.Import/Data/IFCSweptDiskSolid.cs @@ -290,7 +290,7 @@ private IList CreateProfileCurveLoopsForDirectrix(Curve directrix, ou } else - throw ex; + throw; } } diff --git a/Source/Revit.IFC.Import/Data/IFCTriangulatedFaceSet.cs b/Source/Revit.IFC.Import/Data/IFCTriangulatedFaceSet.cs index 5454496e..81025a0d 100644 --- a/Source/Revit.IFC.Import/Data/IFCTriangulatedFaceSet.cs +++ b/Source/Revit.IFC.Import/Data/IFCTriangulatedFaceSet.cs @@ -129,7 +129,7 @@ protected override void Process(IFCAnyHandle ifcTriangulatedFaceSet) if (IFCImportFile.HasUndefinedAttribute(ex)) IFCImportFile.TheFile.DowngradeIFC4SchemaTo(IFCSchemaVersion.IFC4Add1Obsolete); else - throw ex; + throw; } } diff --git a/Source/Revit.IFC.Import/Data/IFCTypeObject.cs b/Source/Revit.IFC.Import/Data/IFCTypeObject.cs index 5eca2c71..bd6589c0 100644 --- a/Source/Revit.IFC.Import/Data/IFCTypeObject.cs +++ b/Source/Revit.IFC.Import/Data/IFCTypeObject.cs @@ -194,8 +194,8 @@ protected override void Create(Document doc) { // If we're "Creating" an Element from an IFCTypeObject during Hybrid IFC Import, then that will already have been imported as a DirectShapeType // So use that instead of creating a whole new DirectShapeType. - ElementId directShapeTypeId = ElementId.InvalidElementId; - if (Importer.TheOptions.IsHybridImport && (Importer.TheHybridInfo?.HybridMap?.TryGetValue(GlobalId, out directShapeTypeId) ?? false)) + ElementId directShapeTypeId = IFCImportHybridInfo.GetHybridMapInformation(Id); + if (IFCImportHybridInfo.IsValidElementId(directShapeTypeId)) { CreatedElementId = directShapeTypeId; } diff --git a/Source/Revit.IFC.Import/Data/IFCTypeProduct.cs b/Source/Revit.IFC.Import/Data/IFCTypeProduct.cs index 47c37001..71fb1660 100644 --- a/Source/Revit.IFC.Import/Data/IFCTypeProduct.cs +++ b/Source/Revit.IFC.Import/Data/IFCTypeProduct.cs @@ -21,6 +21,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using Autodesk.Revit.DB; using Autodesk.Revit.DB.IFC; using Revit.IFC.Common.Enums; using Revit.IFC.Common.Utility; @@ -116,24 +117,24 @@ protected override void Process(IFCAnyHandle ifcTypeProduct) Tag = IFCAnyHandleUtil.GetStringAttribute(ifcTypeProduct, "Tag"); - using (RepresentationsAlreadyCreatedSetter setter = new RepresentationsAlreadyCreatedSetter(GlobalId)) + if (IFCImportHybridInfo.IsValidElementId(IFCImportHybridInfo.GetHybridMapInformation(Id))) + return; + + IList representationMapsHandle = IFCAnyHandleUtil.GetAggregateInstanceAttribute>(ifcTypeProduct, "RepresentationMaps"); + if (representationMapsHandle?.Count > 0) { - IList representationMapsHandle = IFCAnyHandleUtil.GetAggregateInstanceAttribute>(ifcTypeProduct, "RepresentationMaps"); - if (representationMapsHandle?.Count > 0) + foreach (IFCAnyHandle representationMapHandle in representationMapsHandle) { - foreach (IFCAnyHandle representationMapHandle in representationMapsHandle) + IFCRepresentationMap representationMap = IFCRepresentationMap.ProcessIFCRepresentationMap(representationMapHandle); + if (representationMap != null) { - IFCRepresentationMap representationMap = IFCRepresentationMap.ProcessIFCRepresentationMap(representationMapHandle); - if (representationMap != null) - { - RepresentationMaps.Add(representationMap); - - // Traditionally we would create a "dummy" DirectShapeType for each IfcRepresentationMap. In the case where the IfcRepresentationMap is not used by another other IfcTypeProduct, - // we would like to stop creating the "dummy" DirectShapeType and store the geometry in the DirectShapeType associated with the IfcTypeProduct. However, IfcRepresentationMap - // does not have an INVERSE relationship to its IfcTypeProduct(s), at least in IFC2x3. - // As such, we keep track of the IfcRepresentationMaps that have the relationship described above for future correspondence. - RegisterRepresentationMapWithTypeProject(representationMap, this); - } + RepresentationMaps.Add(representationMap); + + // Traditionally we would create a "dummy" DirectShapeType for each IfcRepresentationMap. In the case where the IfcRepresentationMap is not used by another other IfcTypeProduct, + // we would like to stop creating the "dummy" DirectShapeType and store the geometry in the DirectShapeType associated with the IfcTypeProduct. However, IfcRepresentationMap + // does not have an INVERSE relationship to its IfcTypeProduct(s), at least in IFC2x3. + // As such, we keep track of the IfcRepresentationMaps that have the relationship described above for future correspondence. + RegisterRepresentationMapWithTypeProject(representationMap, this); } } } diff --git a/Source/Revit.IFC.Import/Data/IFCUnit.cs b/Source/Revit.IFC.Import/Data/IFCUnit.cs index 2b082ef9..6058f82f 100644 --- a/Source/Revit.IFC.Import/Data/IFCUnit.cs +++ b/Source/Revit.IFC.Import/Data/IFCUnit.cs @@ -958,7 +958,63 @@ void ProcessIFCDerivedUnit(IFCAnyHandle unitHnd) string userDefinedType = IFCImportHandleUtil.GetOptionalStringAttribute(unitHnd, "UserDefinedType", null); if (!string.IsNullOrWhiteSpace(userDefinedType)) { - if (string.Compare(userDefinedType, "Luminous Efficacy", true) == 0) + if (string.Compare(userDefinedType, "Color Temperature", true) == 0) + { + Spec = SpecTypeId.ColorTemperature; + UnitSystem = UnitSystem.Metric; + + // Support only K. + DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.Kelvin, SymbolTypeId.Kelvin); + expectedTypes.AddExpectedType(1, SpecTypeId.HvacTemperature); + expectedTypesList.Add(expectedTypes); + } + else if (string.Compare(userDefinedType, "Cost Per Area", true) == 0) + { + Spec = SpecTypeId.CostPerArea; + UnitSystem = UnitSystem.Metric; + + // Support only $/m2. + DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.CurrencyPerSquareMeter, SymbolTypeId.DollarPerMSup2); + expectedTypes.AddExpectedType(-2, SpecTypeId.Length); + expectedTypesList.Add(expectedTypes); + } + else if (string.Compare(userDefinedType, "Apparent Power Density", true) == 0) + { + Spec = SpecTypeId.ApparentPowerDensity; + UnitSystem = UnitSystem.Metric; + + // Support only VA / m2 = kg * s−3. + DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.VoltAmperesPerSquareMeter, SymbolTypeId.VAPerMSup2); + expectedTypes.AddExpectedType(1, SpecTypeId.Mass); + expectedTypes.AddCustomExpectedType(-3, "TIMEUNIT"); + expectedTypesList.Add(expectedTypes); + } + else if (string.Compare(userDefinedType, "Cost Rate Energy", true) == 0) + { + Spec = SpecTypeId.CostRateEnergy; + UnitSystem = UnitSystem.Metric; + + // Support only $ / (W * h) = kg-1 * m-2 * s2 / 3600. + DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.CurrencyPerWattHour, SymbolTypeId.DollarPerWH); + expectedTypes.AddExpectedType(-1, SpecTypeId.Mass); + expectedTypes.AddExpectedType(-2, SpecTypeId.Length); + expectedTypes.AddCustomExpectedType(2, "TIMEUNIT"); + // TODO + expectedTypesList.Add(expectedTypes); + } + else if (string.Compare(userDefinedType, "Cost Rate Power", true) == 0) + { + Spec = SpecTypeId.CostRatePower; + UnitSystem = UnitSystem.Metric; + + // Support only $ / W = kg-1 * m-2 * s3. + DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.CurrencyPerWatt, SymbolTypeId.DollarPerW); + expectedTypes.AddExpectedType(-1, SpecTypeId.Mass); + expectedTypes.AddExpectedType(-2, SpecTypeId.Length); + expectedTypes.AddCustomExpectedType(3, "TIMEUNIT"); + expectedTypesList.Add(expectedTypes); + } + else if (string.Compare(userDefinedType, "Luminous Efficacy", true) == 0) { Spec = SpecTypeId.Efficacy; UnitSystem = UnitSystem.Metric; @@ -971,16 +1027,38 @@ void ProcessIFCDerivedUnit(IFCAnyHandle unitHnd) expectedTypes.AddExpectedType(1, SpecTypeId.LuminousFlux); expectedTypesList.Add(expectedTypes); } - else if (string.Compare(userDefinedType, "Friction Loss", true) == 0) + else if (string.Compare(userDefinedType, "Luminance", true) == 0) { - Spec = SpecTypeId.HvacFriction; + Spec = SpecTypeId.Luminance; UnitSystem = UnitSystem.Metric; - // Support only Pa / m. - DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.PascalsPerMeter, SymbolTypeId.PaPerM); + // Support only cd / m2. + DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.CandelasPerSquareMeter, SymbolTypeId.CdPerMSup2); + expectedTypes.AddExpectedType(1, SpecTypeId.LuminousIntensity); // TODO check expectedTypes.AddExpectedType(-2, SpecTypeId.Length); + expectedTypesList.Add(expectedTypes); + } + else if (string.Compare(userDefinedType, "Electrical Power Density", true) == 0) + { + Spec = SpecTypeId.ElectricalPowerDensity; + UnitSystem = UnitSystem.Metric; + + // Support W / m2 = kg * s-3 only + DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.WattsPerSquareMeter, SymbolTypeId.WPerMSup2); expectedTypes.AddExpectedType(1, SpecTypeId.Mass); - expectedTypes.AddCustomExpectedType(-2, "TIMEUNIT"); + expectedTypes.AddCustomExpectedType(-3, "TIMEUNIT"); + expectedTypesList.Add(expectedTypes); + } + else if (string.Compare(userDefinedType, "Power Per Length", true) == 0) + { + Spec = SpecTypeId.PowerPerLength; + UnitSystem = UnitSystem.Metric; + + // Support only W / m = kg * m * s-3. + DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.WattsPerMeter, SymbolTypeId.WPerM); + expectedTypes.AddExpectedType(1, SpecTypeId.Mass); + expectedTypes.AddExpectedType(1, SpecTypeId.Length); + expectedTypes.AddCustomExpectedType(-3, "TIMEUNIT"); expectedTypesList.Add(expectedTypes); } else if (string.Compare(userDefinedType, "Electrical Resistivity", true) == 0) @@ -996,6 +1074,280 @@ void ProcessIFCDerivedUnit(IFCAnyHandle unitHnd) expectedTypes.AddExpectedType(-2, SpecTypeId.Current); expectedTypesList.Add(expectedTypes); } + else if (string.Compare(userDefinedType, "Heat Capacity Per Area", true) == 0) + { + Spec = SpecTypeId.HeatCapacityPerArea; + UnitSystem = UnitSystem.Metric; + + // Support only J / (m2 * K) = kg * s-2 * K-1. + DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.JoulesPerSquareMeterKelvin, SymbolTypeId.JPerMSup2K); + expectedTypes.AddExpectedType(1, SpecTypeId.Mass); + expectedTypes.AddCustomExpectedType(-2, "TIMEUNIT"); + expectedTypes.AddExpectedType(-1, SpecTypeId.HvacTemperature); + expectedTypesList.Add(expectedTypes); + } + else if (string.Compare(userDefinedType, "Thermal Gradient Coefficient For Moisture Capacity", true) == 0) + { + Spec = SpecTypeId.ThermalGradientCoefficientForMoistureCapacity; + UnitSystem = UnitSystem.Metric; + + // Support only kg / (kg * K) = K-1. + DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.KilogramsPerKilogramKelvin, SymbolTypeId.KgPerKgK); + expectedTypes.AddExpectedType(-1, SpecTypeId.HvacTemperature); + expectedTypesList.Add(expectedTypes); + } + else if (string.Compare(userDefinedType, "Thermal Mass", true) == 0) + { + Spec = SpecTypeId.ThermalMass; + UnitSystem = UnitSystem.Metric; + + // Support only J / K = kg * m2 * s-2 * K-1. + DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.JoulesPerKelvin, SymbolTypeId.JPerK); + expectedTypes.AddExpectedType(1, SpecTypeId.Mass); + expectedTypes.AddExpectedType(2, SpecTypeId.Length); + expectedTypes.AddCustomExpectedType(-2, "TIMEUNIT"); + expectedTypes.AddExpectedType(-1, SpecTypeId.HvacTemperature); + expectedTypesList.Add(expectedTypes); + } + else if (string.Compare(userDefinedType, "Air Flow Density", true) == 0) + { + Spec = SpecTypeId.AirFlowDensity; + UnitSystem = UnitSystem.Metric; + + // Support only m3 / (h * m2) = m * s-1 / 3600. + DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.CubicMetersPerHourSquareMeter, SymbolTypeId.MSup3PerHMSup2); + expectedTypes.AddExpectedType(1, SpecTypeId.Length); + expectedTypes.AddCustomExpectedType(-1, "TIMEUNIT"); + // TODO + expectedTypesList.Add(expectedTypes); + } + else if (string.Compare(userDefinedType, "Air Flow Divided By Cooling Load", true) == 0) + { + Spec = SpecTypeId.AirFlowDividedByCoolingLoad; + UnitSystem = UnitSystem.Metric; + + // Support only L / (s * kW) = kg–1 * m * s2 * 10–6. + DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.LitersPerSecondKilowatt, SymbolTypeId.LPerSKw); + expectedTypes.AddExpectedType(-1, SpecTypeId.Mass); + expectedTypes.AddExpectedType(1, SpecTypeId.Length); + expectedTypes.AddCustomExpectedType(2, "TIMEUNIT"); + // TODO + expectedTypesList.Add(expectedTypes); + } + else if (string.Compare(userDefinedType, "Air Flow Divided By Volume", true) == 0) + { + Spec = SpecTypeId.AirFlowDividedByVolume; + UnitSystem = UnitSystem.Metric; + + // Support only m3 / (h*m3) = s-1 / 3600. + DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.CubicMetersPerHourCubicMeter, SymbolTypeId.MSup3PerHMSup3); + expectedTypes.AddCustomExpectedType(-1, "TIMEUNIT"); + // TODO + expectedTypesList.Add(expectedTypes); + } + else if (string.Compare(userDefinedType, "Area Divided By Cooling Load", true) == 0) + { + Spec = SpecTypeId.AreaDividedByCoolingLoad; + UnitSystem = UnitSystem.Metric; + + // Support only m2 / kW = s3 * kg-1 * 10-3. + DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.SquareMetersPerKilowatt, SymbolTypeId.MSup2PerKw); + expectedTypes.AddExpectedType(-1, SpecTypeId.Mass); + expectedTypes.AddCustomExpectedType(3, "TIMEUNIT"); + // TODO + expectedTypesList.Add(expectedTypes); + } + else if (string.Compare(userDefinedType, "Area Divided By Heating Load", true) == 0) + { + Spec = SpecTypeId.AreaDividedByHeatingLoad; + UnitSystem = UnitSystem.Metric; + + // Support only m2 / kW = s3 * kg-1 * 10-3. + DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.SquareMetersPerKilowatt, SymbolTypeId.MSup2PerKw); + expectedTypes.AddExpectedType(-1, SpecTypeId.Mass); + expectedTypes.AddCustomExpectedType(3, "TIMEUNIT"); + expectedTypesList.Add(expectedTypes); + } + else if (string.Compare(userDefinedType, "Cooling Load Divided By Area", true) == 0) + { + Spec = SpecTypeId.CoolingLoadDividedByArea; + UnitSystem = UnitSystem.Metric; + + // Support only W / m2 = kg * s−3. + DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.WattsPerSquareMeter, SymbolTypeId.WPerMSup2); + expectedTypes.AddExpectedType(1, SpecTypeId.Mass); + expectedTypes.AddCustomExpectedType(-3, "TIMEUNIT"); + expectedTypesList.Add(expectedTypes); + } + else if (string.Compare(userDefinedType, "Cooling Load Divided By Volume", true) == 0) + { + Spec = SpecTypeId.CoolingLoadDividedByVolume; + UnitSystem = UnitSystem.Metric; + + // Support only W / m3 = kg * m-1 * s-3. + DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.WattsPerCubicMeter, SymbolTypeId.WPerMSup3); + expectedTypes.AddExpectedType(1, SpecTypeId.Mass); + expectedTypes.AddExpectedType(-1, SpecTypeId.Length); + expectedTypes.AddCustomExpectedType(-3, "TIMEUNIT"); + expectedTypesList.Add(expectedTypes); + } + else if (string.Compare(userDefinedType, "Flow Per Power", true) == 0) + { + Spec = SpecTypeId.FlowPerPower; + UnitSystem = UnitSystem.Metric; + + // Support only m3 / (W * s) = kg-1 * m * s2. + DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.CubicMetersPerWattSecond, SymbolTypeId.MSup3PerWS); + expectedTypes.AddExpectedType(-1, SpecTypeId.Mass); + expectedTypes.AddExpectedType(1, SpecTypeId.Length); + expectedTypes.AddCustomExpectedType(2, "TIMEUNIT"); + expectedTypesList.Add(expectedTypes); + } + else if (string.Compare(userDefinedType, "Friction Loss", true) == 0) + { + Spec = SpecTypeId.HvacFriction; + UnitSystem = UnitSystem.Metric; + + // Support only Pa / m = kg * m-2 * s-2. + DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.PascalsPerMeter, SymbolTypeId.PaPerM); + expectedTypes.AddExpectedType(1, SpecTypeId.Mass); + expectedTypes.AddExpectedType(-2, SpecTypeId.Length); + expectedTypes.AddCustomExpectedType(-2, "TIMEUNIT"); + expectedTypesList.Add(expectedTypes); + } + else if (string.Compare(userDefinedType, "Heating Load Divided By Area", true) == 0) + { + Spec = SpecTypeId.HeatingLoadDividedByArea; + UnitSystem = UnitSystem.Metric; + + // Support only W / m2 = kg * s−3. + DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.WattsPerSquareMeter, SymbolTypeId.WPerMSup2); + expectedTypes.AddExpectedType(1, SpecTypeId.Mass); + expectedTypes.AddCustomExpectedType(-3, "TIMEUNIT"); + expectedTypesList.Add(expectedTypes); + } + else if (string.Compare(userDefinedType, "Heating Load Divided By Volume", true) == 0) + { + Spec = SpecTypeId.HeatingLoadDividedByVolume; + UnitSystem = UnitSystem.Metric; + + // Support only W / m3 = kg * m-1 * s-3. + DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.WattsPerCubicMeter, SymbolTypeId.WPerMSup3); + expectedTypes.AddExpectedType(1, SpecTypeId.Mass); + expectedTypes.AddExpectedType(-1, SpecTypeId.Length); + expectedTypes.AddCustomExpectedType(-3, "TIMEUNIT"); + expectedTypesList.Add(expectedTypes); + } + else if (string.Compare(userDefinedType, "Power Per Flow", true) == 0) + { + Spec = SpecTypeId.PowerPerFlow; + UnitSystem = UnitSystem.Metric; + + // Support only (W * s) / m3 = kg * m-1 * s-2. + DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.WattsPerCubicMeterPerSecond, SymbolTypeId.WSPerMSup3); + expectedTypes.AddExpectedType(1, SpecTypeId.Mass); + expectedTypes.AddExpectedType(-1, SpecTypeId.Length); + expectedTypes.AddCustomExpectedType(-2, "TIMEUNIT"); + expectedTypesList.Add(expectedTypes); + } + else if (string.Compare(userDefinedType, "Piping Friction", true) == 0) + { + Spec = SpecTypeId.PipingFriction; + UnitSystem = UnitSystem.Metric; + + // Support only Pa / m = kg * m-2 * s-2. + DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.PascalsPerMeter, SymbolTypeId.PaPerM); + expectedTypes.AddExpectedType(1, SpecTypeId.Mass); + expectedTypes.AddExpectedType(-2, SpecTypeId.Length); + expectedTypes.AddCustomExpectedType(-2, "TIMEUNIT"); + expectedTypesList.Add(expectedTypes); + } + else if (string.Compare(userDefinedType, "Area Spring Coefficient", true) == 0) + { + Spec = SpecTypeId.AreaSpringCoefficient; + UnitSystem = UnitSystem.Metric; + + // Support only Pa / m = kg * m-2 * s-2. + DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.PascalsPerMeter, SymbolTypeId.PaPerM); + expectedTypes.AddExpectedType(1, SpecTypeId.Mass); + expectedTypes.AddExpectedType(-2, SpecTypeId.Length); + expectedTypes.AddCustomExpectedType(-2, "TIMEUNIT"); + expectedTypesList.Add(expectedTypes); + } + else if (string.Compare(userDefinedType, "Line Spring Coefficient", true) == 0) + { + Spec = SpecTypeId.LineSpringCoefficient; + UnitSystem = UnitSystem.Metric; + + // Support only Pa = kg * m-1 * s-2. + DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.Pascals, SymbolTypeId.Pa); + expectedTypes.AddExpectedType(1, SpecTypeId.Mass); + expectedTypes.AddExpectedType(-1, SpecTypeId.Length); + expectedTypes.AddCustomExpectedType(-2, "TIMEUNIT"); + expectedTypesList.Add(expectedTypes); + } + else if (string.Compare(userDefinedType, "Mass Per Unit Area", true) == 0) + { + Spec = SpecTypeId.MassPerUnitArea; + UnitSystem = UnitSystem.Metric; + + // Support only kg / m2 = kg * m-2. + DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.KilogramsPerSquareMeter, SymbolTypeId.KgPerMSup2); + expectedTypes.AddExpectedType(1, SpecTypeId.Mass); + expectedTypes.AddExpectedType(-2, SpecTypeId.Length); + expectedTypesList.Add(expectedTypes); + } + else if (string.Compare(userDefinedType, "Reinforcement Area Per Unit Length", true) == 0) + { + Spec = SpecTypeId.ReinforcementAreaPerUnitLength; + UnitSystem = UnitSystem.Metric; + + // Support only m2 / m = m. + DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.SquareMetersPerMeter, SymbolTypeId.MSup2PerM); + expectedTypes.AddExpectedType(1, SpecTypeId.Length); + expectedTypesList.Add(expectedTypes); + } + else if (string.Compare(userDefinedType, "Rotational Line Spring Coefficient", true) == 0) + { + Spec = SpecTypeId.RotationalLineSpringCoefficient; + UnitSystem = UnitSystem.Metric; + + // Support only kn-m / (deg/m) = 10+3 kg * m3 * s-2 * rad-1. + DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.KilonewtonMetersPerDegreePerMeter, SymbolTypeId.KNDashMPerDegreePerM); + expectedTypes.AddExpectedType(1, SpecTypeId.Mass); + expectedTypes.AddExpectedType(1, SpecTypeId.Length); + expectedTypes.AddCustomExpectedType(-2, "TIMEUNIT"); + expectedTypes.AddExpectedType(-1, SpecTypeId.Angle); + // TODO + expectedTypesList.Add(expectedTypes); + } + else if (string.Compare(userDefinedType, "Rotational Point Spring Coefficient", true) == 0) + { + Spec = SpecTypeId.RotationalPointSpringCoefficient; + UnitSystem = UnitSystem.Metric; + + // Support only kn-m / deg = 10+3 kg * m2 * s-2 * rad-1. + DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.KilonewtonMetersPerDegree, SymbolTypeId.KNDashMPerDegree); + expectedTypes.AddExpectedType(1, SpecTypeId.Mass); + expectedTypes.AddExpectedType(2, SpecTypeId.Length); + expectedTypes.AddCustomExpectedType(-2, "TIMEUNIT"); + expectedTypes.AddExpectedType(-1, SpecTypeId.Angle); + // TODO + expectedTypesList.Add(expectedTypes); + } + else if (string.Compare(userDefinedType, "Unit Weight", true) == 0) + { + Spec = SpecTypeId.UnitWeight; + UnitSystem = UnitSystem.Metric; + + // Support only kN / m3 = 10+3 kg * m-2 * s-2 * 10-3. + DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.KilonewtonsPerCubicMeter, SymbolTypeId.KNPerMSup3); + expectedTypes.AddExpectedType(1, SpecTypeId.Mass); + expectedTypes.AddExpectedType(-2, SpecTypeId.Length); + expectedTypes.AddCustomExpectedType(-2, "TIMEUNIT"); + // TODO + expectedTypesList.Add(expectedTypes); + } } } diff --git a/Source/Revit.IFC.Import/Data/IFCZone.cs b/Source/Revit.IFC.Import/Data/IFCZone.cs index 3b791bd2..e54d8656 100644 --- a/Source/Revit.IFC.Import/Data/IFCZone.cs +++ b/Source/Revit.IFC.Import/Data/IFCZone.cs @@ -85,7 +85,10 @@ public static IFCZone ProcessIFCZone(IFCAnyHandle ifcZone) /// True if the IFC entity geometry should be duplicated, False otherwise. public override bool ContainerFilteredEntity(IFCEntity entity) { - return (entity is IFCSpace); + if (entity == null) + return false; + + return (entity.EntityType == IFCEntityType.IfcSpace) || (entity.EntityType == IFCEntityType.IfcSpatialZone); } /// diff --git a/Source/Revit.IFC.Import/Enums/IFCSchemaVersion.cs b/Source/Revit.IFC.Import/Enums/IFCSchemaVersion.cs index da2206b0..e026dca2 100644 --- a/Source/Revit.IFC.Import/Enums/IFCSchemaVersion.cs +++ b/Source/Revit.IFC.Import/Enums/IFCSchemaVersion.cs @@ -44,6 +44,7 @@ public enum IFCSchemaVersion IFC4x2, IFC4x3_RC1, IFC4x3_RC4, - IFC4x3 + IFC4x3, + IFC4x3_ADD2 } } \ No newline at end of file diff --git a/Source/Revit.IFC.Import/Geometry/IFCGeometryUtil.cs b/Source/Revit.IFC.Import/Geometry/IFCGeometryUtil.cs index c540e65b..d81498d7 100644 --- a/Source/Revit.IFC.Import/Geometry/IFCGeometryUtil.cs +++ b/Source/Revit.IFC.Import/Geometry/IFCGeometryUtil.cs @@ -622,6 +622,49 @@ private static bool HasSuspiciousNumberOfCurveSegments(int id, IFCCurve ifcCurve return true; } + /// + /// Check that a geometric object is valid for a DirectShape, and adjust if needed. + /// + /// The original GeometryObject. + /// An optional DirectShape uesd to validate solids. + /// The id of the entity being processed. + /// Null if the original object is valid, or a list of GeometryObjects if not. + public static IList AdjustGeometryObjectsIfNeeded(GeometryObject originalObject, DirectShape shape, int id) + { + if (shape != null && originalObject is Solid) + { + Solid solid = originalObject as Solid; + if (!shape.IsValidGeometry(solid)) + { + Importer.TheLog.LogWarning(id, "Couldn't create valid solid, reverting to mesh.", false); + return CreateMeshesFromSolid(solid); + } + } + + Curve curve = originalObject as Curve; + if (!(curve?.IsBound ?? true)) + { + if (curve?.IsCyclic ?? false) + { + double period = curve.Period; + Curve newCurve = curve.Clone(); + + curve.MakeBound(0, period / 2); + newCurve.MakeBound(period / 2, period); + + return new List() { curve, newCurve }; + } + else + { + Importer.TheLog.LogWarning(id, "Found unbounded acyclic curve, ignoring.", false); + return new List(); + } + } + + return null; + } + + /// /// Given a list of curves, finds any unbound cyclic curves and splits them. /// @@ -947,7 +990,7 @@ public static Solid ExecuteSafeBooleanOperation(int id, int secondId, Solid firs // This is the only error that we are trying to catch and fix. // For any other error, we will re-throw. if (!msg.Contains("Failed to perform the Boolean operation for the two solids")) - throw ex; + throw; if (ii < numPasses - 1) continue; diff --git a/Source/Revit.IFC.Import/Importer.cs b/Source/Revit.IFC.Import/Importer.cs index ca366fef..0b503bc0 100644 --- a/Source/Revit.IFC.Import/Importer.cs +++ b/Source/Revit.IFC.Import/Importer.cs @@ -195,7 +195,7 @@ public static Importer CreateImporter(Document originalDocument, string ifcFileN Importer importer = new Importer(); TheImporter = importer; TheCache = IFCImportCache.Create(originalDocument, ifcFileName); - TheOptions = importer.m_ImportOptions = IFCImportOptions.Create(importOptions, ifcFileName, originalDocument); + TheOptions = importer.m_ImportOptions = IFCImportOptions.Create(importOptions); TheLog = IFCImportLog.CreateLog(ifcFileName, "log.html", !TheOptions.DisableLogging); return importer; } @@ -525,42 +525,44 @@ private void LogEndImportDetailed(Document ifcDocument) IList directShapeElements = collector.ToElements(); // This is inefficient, but we need to reliably get the IFCGuids - // HybridMap is for IFC GlobalId --> ElementId. This is used for almost all of the Hybrid IFC Import processing. - // reverseLookup is for ElementId --> IFC GlobalId. This is used to find the ElementId associated with a given IFC GlobalId (for logging purposes). - IDictionary reverseLookup = new Dictionary(); - foreach (KeyValuePair pair in TheHybridInfo.HybridMap) + if (Importer.TheHybridInfo?.HybridMap != null) { - try + // HybridMap is for IFC STEP Id --> ElementId. This is used for almost all of the Hybrid IFC Import processing. + // reverseLookup is for ElementId --> IFC STEP Id. This is used to find the ElementId associated with a given IFC STEP Id (for logging purposes). + IDictionary reverseLookup = new Dictionary(); + foreach (KeyValuePair pair in TheHybridInfo.HybridMap) { - ElementId elementId = pair.Value; - string ifcGuid = pair.Key; - reverseLookup.Add(pair.Value, pair.Key); + try + { + ElementId elementId = pair.Value; + string stepId = pair.Key; + reverseLookup.Add(elementId, stepId); + } + catch (ArgumentException ex) + { + TheLog.LogWarning(-1, $"Duplicate ElementId found when reversing Hybrid Map for logging {ex.Message}", false); + } } - catch (ArgumentException ex) + + // Log (into journal) IFC STEP Ids & ElementIds that were imported by AnyCAD or via Revit alone. + ifcDocument.Application.WriteJournalComment($"Hybrid IFC Import: Count of DirectShapes imported via AnyCAD: {Importer.TheHybridInfo.HybridElements.Count}", false); + foreach (Element element in directShapeElements) { - TheLog.LogWarning(-1, $"Duplicate ElementId found when reversing Hybrid Map for logging {ex.Message}", false); + string stepId; + if (reverseLookup.TryGetValue(element.Id, out stepId)) + { + ifcDocument.Application.WriteJournalComment($"Hybrid IFC Import: AnyCAD DirectShape (IFC STEP Id, ElementId): ({stepId}, {element.Id})", false); + } } - } - // Log (into journal) IFC GlobalIds & ElementIds that were imported by AnyCAD or via Revit alone. - ifcDocument.Application.WriteJournalComment($"Hybrid IFC Import: Count of DirectShapes imported via AnyCAD: {Importer.TheHybridInfo.HybridElements.Count}", false); - foreach (Element element in directShapeElements) - { - string ifcGuid; - if (reverseLookup.TryGetValue(element.Id, out ifcGuid)) + ifcDocument.Application.WriteJournalComment($"Hybrid IFC Import: Count of DirectShapes falling back to Revit: {numDirectShapes - Importer.TheHybridInfo.HybridElements.Count}", false); + foreach (Element element in directShapeElements) { - ifcDocument.Application.WriteJournalComment($"Hybrid IFC Import: AnyCAD DirectShape (IFC GUID, ElementId): ({ifcGuid}, {element.Id})", false); + if (reverseLookup.ContainsKey(element.Id)) + continue; + ifcDocument.Application.WriteJournalComment($"Hybrid IFC Import: Fallback DirectShape ElementId: ({element.Id})", false); } } - - ifcDocument.Application.WriteJournalComment($"Hybrid IFC Import: Count of DirectShapes falling back to Revit: {numDirectShapes - Importer.TheHybridInfo.HybridElements.Count}", false); - foreach (Element element in directShapeElements) - { - if (reverseLookup.ContainsKey(element.Id)) - continue; - string ifcGuid = IFCGUIDUtil.GetGUID(element); - ifcDocument.Application.WriteJournalComment($"Hybrid IFC Import: Fallback DirectShape (IFC GUID, ElementId): ({ifcGuid}, {element.Id})", false); - } } } @@ -696,7 +698,7 @@ public void ImportIFC(ImporterIFC importer) string fullIFCFileName = importer.FullFileName; IDictionary options = importer.GetOptions(); - TheOptions = m_ImportOptions = IFCImportOptions.Create(options, fullIFCFileName, importer.Document); + TheOptions = m_ImportOptions = IFCImportOptions.Create(options); // An early check, based on the options set - if we are allowed to use an up-to-date existing file on disk, use it. try @@ -728,9 +730,9 @@ public void ImportIFC(ImporterIFC importer) finally { TheLog?.Close(); - TheLog = null; IFCImportFile.TheFile?.Close(); TheHybridInfo = null; + TheLog = null; } } diff --git a/Source/Revit.IFC.Import/Properties/AssemblyInfo.cs b/Source/Revit.IFC.Import/Properties/AssemblyInfo.cs index 5bbc2056..f351ccce 100644 --- a/Source/Revit.IFC.Import/Properties/AssemblyInfo.cs +++ b/Source/Revit.IFC.Import/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ using System.Reflection; -#if IFC_OPENSOURCE // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. @@ -8,18 +7,12 @@ [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Autodesk")] [assembly: AssemblyProduct("IFC Import for Revit")] -[assembly: AssemblyCopyright("@2012-2022 Autodesk, Inc. All rights reserved.")] +[assembly: AssemblyCopyright("@2012-2024 Autodesk, Inc. All rights reserved.")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -[assembly: AssemblyVersion("24.2.0.49")] -[assembly: AssemblyFileVersion("24.2.0.49")] -#endif - -#region Using directives - - -#endregion +[assembly: AssemblyVersion("25.2.0.5")] +[assembly: AssemblyFileVersion("25.2.0.5")] diff --git a/Source/Revit.IFC.Import/Revit.IFC.Import.csproj b/Source/Revit.IFC.Import/Revit.IFC.Import.csproj index ef25bbdd..ba11a3e3 100644 --- a/Source/Revit.IFC.Import/Revit.IFC.Import.csproj +++ b/Source/Revit.IFC.Import/Revit.IFC.Import.csproj @@ -1,333 +1,49 @@ - - + - Debug - x86 - 8.0.30703 - 2.0 - {7F987D09-9716-4F50-ADE0-278E4B537101} - Library - Properties Revit.IFC.Import Revit.IFC.Import - v4.8 - - - 512 - {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - 4 - Publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true - Revit.IFC + true + - - - - - false - x64 - C:\ProgramData\Autodesk\ApplicationPlugins\IFC 2024.bundle\Contents\2024\ - - - false - bin\Releasex64\ - x64 - - - - False - ..\ThirdParty\ICSharpCode\ICSharpCode.SharpZipLib.DLL - true - - - False - ..\..\..\..\Program Files\Autodesk\Revit 2024\RevitAPI.dll - - - False - ..\..\..\..\Program Files\Autodesk\Revit 2024\RevitAPIIFC.dll - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + True True Resources.resx - - - - - - - - - - - - - - - - - - - - - - - - - - False - .NET Framework 2.0 %28x86%29 - false - - - False - .NET Framework 3.0 %28x86%29 - true - - - False - .NET Framework 3.5 - false - - - False - Windows Installer 3.1 - true - - {032EA4DC-181F-4453-9F93-E08DE1C07D95} - Revit.IFC.Common False + All + All - {b1e159b7-4b12-45a9-b83f-159e37798d44} - Revit.IFC.Import.Core + False + All + All + ResXFileCodeGenerator Resources.Designer.cs - - - - - - - - - \ No newline at end of file + + + + + + ..\..\..\..\Program Files\Autodesk\Revit 2025\RevitAPI.dll + + + ..\..\..\..\Program Files\Autodesk\Revit 2025\RevitAPIIFC.dll + + + diff --git a/Source/Revit.IFC.Import/Revit.IFC.Import.props b/Source/Revit.IFC.Import/Revit.IFC.Import.props deleted file mode 100644 index 0e84fc8e..00000000 --- a/Source/Revit.IFC.Import/Revit.IFC.Import.props +++ /dev/null @@ -1,25 +0,0 @@ - - - - bin\Debugx64\ - DEBUG;TRACE;IFC_OPENSOURCE - true - false - false - 4 - full - prompt - - - bin\Releasex64\ - TRACE;IFC_OPENSOURCE - false - true - false - 4 - none - prompt - - - - diff --git a/Source/Revit.IFC.Import/Utility/IFCCategoryUtil.cs b/Source/Revit.IFC.Import/Utility/IFCCategoryUtil.cs index 1d86652a..1b7d8a36 100644 --- a/Source/Revit.IFC.Import/Utility/IFCCategoryUtil.cs +++ b/Source/Revit.IFC.Import/Utility/IFCCategoryUtil.cs @@ -557,6 +557,8 @@ private static void InitEntityTypeToCategoryMaps() m_EntityTypeToCategory[IFCEntityType.IfcSpaceType] = BuiltInCategory.OST_GenericModel; m_EntityTypeToCategory[IFCEntityType.IfcSpaceHeater] = BuiltInCategory.OST_MechanicalEquipment; m_EntityTypeToCategory[IFCEntityType.IfcSpaceHeaterType] = BuiltInCategory.OST_MechanicalEquipment; + m_EntityTypeToCategory[IFCEntityType.IfcSpatialZone] = BuiltInCategory.OST_GenericModel; + m_EntityTypeToCategory[IFCEntityType.IfcSpatialZoneType] = BuiltInCategory.OST_GenericModel; m_EntityTypeToCategory[IFCEntityType.IfcStair] = BuiltInCategory.OST_Stairs; m_EntityTypeToCategory[IFCEntityType.IfcStairType] = BuiltInCategory.OST_Stairs; m_EntityTypeToCategory[IFCEntityType.IfcStairFlight] = BuiltInCategory.OST_Stairs; @@ -894,6 +896,63 @@ public static bool CanImport(IFCEntityType type, string predefinedType) return true; } + private static Category GetCategoryFromAcceptableNames(CategoryNameMap subcategories, string subCategoryName) + { + try + { + Category subCategory = subcategories.get_Item(subCategoryName); + if (subCategory != null) + return subCategory; + } + catch + { + } + + if (!Importer.TheOptions.IsHybridImport) + return null; + + // If we are doing hybrid import, try some other acceptable alternatives. + try + { + // First attempt: remove "Type". + int removeTypeLocation = subCategoryName.LastIndexOf("Type."); + if (removeTypeLocation > 0) + { + string altSubCategoryName = subCategoryName.Replace("Type.", "."); + Category subCategory = subcategories.get_Item(altSubCategoryName); + if (subCategory != null) + return subCategory; + } + } + catch + { + } + + try + { + // Second attempt: uppercase predefined type. + int predefinedTypeLocation = subCategoryName.LastIndexOf("."); + if (predefinedTypeLocation > 0) + { + string[] nameAndPredefinedType = subCategoryName.Split('.'); + if (nameAndPredefinedType.Count() == 2) + { + nameAndPredefinedType[1] = nameAndPredefinedType[1].ToUpper(); + string altSubCategoryName = string.Join(".", nameAndPredefinedType); + + Category subCategory = subcategories.get_Item(altSubCategoryName); + if (subCategory != null) + return subCategory; + } + } + } + catch + { + } + + return null; + } + private static Category GetOrCreateSubcategory(Document doc, int id, string subCategoryName, ElementId categoryId) { if (string.IsNullOrWhiteSpace(subCategoryName)) @@ -907,18 +966,8 @@ private static Category GetOrCreateSubcategory(Document doc, int id, string subC IDictionary createdSubcategories = Importer.TheCache.CreatedSubcategories; if (!createdSubcategories.TryGetValue(subCategoryName, out subCategory)) { - // Category may have been created by a previous action (probably a previous import). Look first. - // First check GenericModels. - // - try - { - CategoryNameMap subcategories = Importer.TheCache.GenericModelsCategory.SubCategories; - subCategory = subcategories.get_Item(subCategoryName); - } - catch - { - subCategory = null; - } + subCategory = GetCategoryFromAcceptableNames(Importer.TheCache.GenericModelsCategory?.SubCategories, + subCategoryName); // Then Topography. // diff --git a/Source/Revit.IFC.Import/Utility/IFCImportCache.cs b/Source/Revit.IFC.Import/Utility/IFCImportCache.cs index 62e8d676..3ac5b030 100644 --- a/Source/Revit.IFC.Import/Utility/IFCImportCache.cs +++ b/Source/Revit.IFC.Import/Utility/IFCImportCache.cs @@ -33,6 +33,8 @@ namespace Revit.IFC.Import.Utility /// public class IFCImportCache { + public AllocatedGeometryObjectCache AllocatedGeometryObjectCache { get; set; } = new AllocatedGeometryObjectCache(); + /// /// The ParameterBindings map associated with accessed documents. /// diff --git a/Source/Revit.IFC.Import/Utility/IFCImportHybridInfo.cs b/Source/Revit.IFC.Import/Utility/IFCImportHybridInfo.cs index e6c46d7e..c39541c7 100644 --- a/Source/Revit.IFC.Import/Utility/IFCImportHybridInfo.cs +++ b/Source/Revit.IFC.Import/Utility/IFCImportHybridInfo.cs @@ -31,42 +31,11 @@ namespace Revit.IFC.Import.Utility { + /// - /// A helper class to set and unset RepresentationsAlreadyCreated, with the "using" keyword. + /// Provide methods to perform Hybrid IFC Import. /// - public class RepresentationsAlreadyCreatedSetter : IDisposable - { - /// - /// The constructor. - /// - /// The GUID to check. - public RepresentationsAlreadyCreatedSetter(string guid) - { - // IFCRepresentationItem should know that it is processing something for Hybrid IFC Imports. - // Then it will create IFCHybridRepresentationItems, which are placeholders for body geometry created via AnyCAD. - // This is so data for Representation Item will still exist, even if legacy geometry does not. - if (Importer.TheHybridInfo?.HybridMap?.ContainsKey(guid) ?? false) - { - Importer.TheHybridInfo.RepresentationsAlreadyCreated = true; - } - } - - /// - /// The Dispose method. - /// - public void Dispose() - { - if (Importer.TheHybridInfo != null) - { - Importer.TheHybridInfo.RepresentationsAlreadyCreated = false; - } - } - } - -/// -/// Provide methods to perform Hybrid IFC Import. -/// -public class IFCImportHybridInfo + public class IFCImportHybridInfo { /// /// Keeps track of Elements imported (DirectShape/DirectShapeTypes) by AnyCAD @@ -74,7 +43,7 @@ public class IFCImportHybridInfo public IList HybridElements { get; set; } = new List(); /// - /// Map from IFCGuid --> Revit ElementId so legacy IFC Processing can find Elements. + /// Map from IFC STEP Id --> Revit ElementId so legacy IFC Processing can find Elements. /// public IDictionary HybridMap { get; set; } = new Dictionary(); @@ -83,19 +52,6 @@ public class IFCImportHybridInfo /// public IList ElementsToDelete { get; set; } = new List(); - /// - /// For IFCProject, Revit will still need to process IFCProductRepresentation/IFCRepresentation/IFCRepresentationItem. - /// For IFCProjectType, Revit will still need to process IFCRepresentationMap/IFCRepresentation/IFCRepresentationItem. - /// An example of data that must exist: LayerAssignment. - /// In both cases, body geometry will have been created by AnyCAD during pass one, so new body geometry cannot be created. - /// Communication must be made to IFCRepresentationItem that the IFCProduct/IFCProductType has already had its Representation Created. - /// That is what this flag indicates: - /// True: Representation (Body geometry) already created during pass one. Ignore all RepresentationItems that might create meshes, etc. The only - /// exception to this is points and curves. Instead an IFCHybridRepresentationItem will be created as a placeholder. - /// False: Representation (Body geometry) should be created like normal with Legacy IFC Import. - /// - public bool RepresentationsAlreadyCreated { get; set; } = false; - /// /// Document into which IFC Import occurs. /// @@ -111,13 +67,6 @@ public class IFCImportHybridInfo /// public XYZ LargeCoordinateOriginOffset { get; set; } = XYZ.Zero; - /// - /// Keeps track of one-to-many mapping of entities that will result in container to sub-Element relationships. - /// Key: stepId of the container entity. - /// Value: Set of IfcObjectDefinition entities that result in sub-Elements. - /// - public IDictionary> ContainerMap { get; set; } = null; - /// /// Internal reference to the class that is responsible for doing the actual import and Map creation. /// @@ -149,37 +98,36 @@ public IFCImportHybridInfo(Document ifcDocument, string ifcInputFile, bool doUpd // Import Elements // int? elementsImported = ImportElements(doUpdate); - if (elementsImported == null) + if (!elementsImported.HasValue) { Importer.TheLog.LogError(-1, "Hybrid IFC Import: Unknown Error during Element Import -- aborting", true); return; } - if (elementsImported == 0) + if (elementsImported.Value == 0) { Importer.TheLog.LogError(-1, "Hybrid IFC Import: elementsImportedList empty -- reverting to fallback for entire import.", false); return; } - // Associate Imported Elements with IFC Guids - // - int? associationsPerformed = AssociateElementsWithIFCGuids(); - if (associationsPerformed == null) + HybridMap = HybridImporter.GetIFCStepIdToElementIdMap(); + if (HybridMap == null) { - Importer.TheLog.LogError(-1, "Hybrid IFC Import: Unknown Error during Element / IFC Guid association.", true); + Importer.TheLog.LogError(-1, "Hybrid IFC Import: Unknown Error during IFC STEP Id/ElementId map creation.", true); return; } - // Not an error, but this may hinder the Import Later. - if (associationsPerformed != elementsImported) + if (HybridMap.Count != elementsImported.Value) { - Importer.TheLog.LogWarning(-1, "Hybrid IFC Import: Number of Element / IFC Guid associations do not match number of imported Elements.", false); + // Not an error, but this may hinder the Import Later. + Importer.TheLog.LogComment(-1, "Hybrid IFC Import: Number of IFC STEP Id/ElementIds associations do not match number of imported Elements. Not an error.", true); } + if (Importer.TheOptions.VerboseLogging) { Importer.TheLog.LogComment(-1, "--- Hybrid IFC Import: Start of Logging detailed Information about AnyCAD Import ---", false); - Importer.TheLog.LogComment(-1, "Hybrid IFC Import: If an IfcGuid does not appear in the following list, then it will fallback to Revit processing ---", false); + Importer.TheLog.LogComment(-1, "Hybrid IFC Import: If an IFC STEP Id does not appear in the following list, then it will fallback to Revit processing ---", false); LogImportedElementsDetailed(); LogHybridMapDetailed(); Importer.TheLog.LogComment(-1, "--- Hybrid IFC Import: End of Logging detailed Information about AnyCAD Import ---", false); @@ -197,6 +145,7 @@ public IFCImportHybridInfo(Document ifcDocument, string ifcInputFile, bool doUpd public void LogImportedElementsDetailed() { Importer.TheLog.LogComment(-1, "--- Hybrid IFC Import: Start Imported Element Details. ---", false); + Options options = new Options(); foreach (ElementId elementId in HybridElements) { DirectShape shape = IfcDocument?.GetElement(elementId) as DirectShape; @@ -206,15 +155,27 @@ public void LogImportedElementsDetailed() continue; } - ElementId directShapeType = shape.TypeId; - if ((directShapeType ?? ElementId.InvalidElementId) == ElementId.InvalidElementId) + // GeometryInstance for DirectShape indicates the DirectShapeType for the DirectShape. This DirectShapeType holds Geometry for DirectShape. + // This may differ from DirectShape.TypeId. + ElementId geometricDSTElementId = ElementId.InvalidElementId; + GeometryElement geometryElement = shape.get_Geometry(options); + if (geometryElement != null) { - Importer.TheLog.LogComment(-1, $"Hybrid IFC Import: DirectShape Imported with no DirectShapeType: {elementId}.", false); - } - else - { - Importer.TheLog.LogComment(-1, $"Hybrid IFC Import: (DirectShape, DirectShapeType) Imported: ({elementId}, {directShapeType}).", false); + foreach (GeometryObject geometryObject in geometryElement) + { + GeometryInstance geomInstance = geometryObject as GeometryInstance; + if (geomInstance == null) + { + continue; + } + + geometricDSTElementId = geomInstance.GetSymbolGeometryId().SymbolId; + break; + } } + + // Log Comment for all three -- (DirectShape, GeomInstance DirectShapeType, TypeId) + Importer.TheLog.LogComment(-1, $"Hybrid IFC Import: (DirectShape, Parametric DirectShapeType, Geometric DirectShapeType): ({elementId}, {shape.TypeId}, {geometricDSTElementId})", false); } Importer.TheLog.LogComment(-1, "--- Hybrid IFC Import: End Imported Element Details. ---", false); } @@ -222,7 +183,7 @@ public void LogImportedElementsDetailed() /// /// Log information about the Hybrid IFC Import Association Map (IFC GlobalId --> Revit ElementId). /// - public void LogHybridMapDetailed () + public void LogHybridMapDetailed() { Importer.TheLog.LogComment(-1, "--- Hybrid IFC Import: Start Hybrid Map Details. ---", false); if (HybridMap == null) @@ -239,23 +200,15 @@ public void LogHybridMapDetailed () { foreach (var mapEntry in HybridMap) { - string ifcGuid = mapEntry.Key; + string stepId = mapEntry.Key; ElementId elementId = mapEntry.Value; - if (!string.IsNullOrEmpty(ifcGuid) && ((elementId ?? ElementId.InvalidElementId) != ElementId.InvalidElementId)) - { - Importer.TheLog.LogComment(-1, $"Hybrid IFC Import: Map Entry Created (IFC Guid, ElementId): ({mapEntry.Key}, {mapEntry.Value})", false); - continue; - } - - if (!string.IsNullOrEmpty(ifcGuid)) + if (elementId == ElementId.InvalidElementId) { - Importer.TheLog.LogComment(-1, "Hybrid IFC Import: Hybrid Map entry has no IFC Guid.", false); - continue; + Importer.TheLog.LogComment(-1, $"Hybrid IFC Import: Hybrid Map entry has no ElementId for {stepId}", false); } - - if ((elementId ?? ElementId.InvalidElementId) != ElementId.InvalidElementId) - { - Importer.TheLog.LogComment(-1, $"Hybrid IFC Import: Hybrid Map entry has no ElementId for {ifcGuid}", false); + else + { + Importer.TheLog.LogComment(-1, $"Hybrid IFC Import: Map Entry Created (IFC STEP Id, ElementId): ({stepId}, {elementId})", false); } } } @@ -316,17 +269,7 @@ public void LogElementsToDeleteDetailed() if (update) { - //IFC Extension back - compatibility: - //HybridImporter.UpdateElements method available since Revit 2024.1, handle it for addin usage with the previous Revit versions. - // - try - { - TryToUpdateElements(); - } - catch(MissingMethodException) - { - HybridElements = HybridImporter.ImportElements(IfcDocument, IfcInputFile); - } + HybridElements = HybridImporter.UpdateElements(IfcDocument, IfcInputFile); } else { @@ -336,129 +279,6 @@ public void LogElementsToDeleteDetailed() return HybridElements?.Count; } - private void TryToUpdateElements() - { - HybridElements = HybridImporter.UpdateElements(IfcDocument, IfcInputFile); - } - - /// - /// Associate ElementIds with IFCGuids. In other words, populate the IFCGuid --> ElementId map. - /// - /// Number of entries in the map. - /// - public int? AssociateElementsWithIFCGuids() - { - if (HybridImporter == null) - { - throw new InvalidOperationException("Attempting to associate Elements with IfcGuids with null IFCHybridImporter"); - } - - if (IfcDocument == null) - { - Importer.TheLog.LogError(-1, "No document for Hybrid IFC Import", true); - return null; - } - - // CreateMap actually returns an ElementId-to-String map. This is because of two things: - // 1. We don't know if an external API does a case-sensitive comparison (which is extremely important for IFC GUIDS). - // 2. We do know that System.String uses a case-sensitive comparison. - // And then convert. - IDictionary hybridImportMap = HybridImporter.CreateMap(IfcDocument, HybridElements); - if (hybridImportMap == null) - { - Importer.TheLog.LogError(-1, "Hybrid IFC Import Map set to invalid value.", true); - return null; - } - - // IFCGuidKey exists for the sole purpose of retrieving the map using a well-defined operator< in C++. - foreach (KeyValuePair elementIdGuidPair in hybridImportMap) - { - // Use string for IFC Global from here on out. IFCGuidKey is not generic enough to use as an IFC Global Id elsewhere. - string ifcGuid = elementIdGuidPair.Key.IFCGlobalId; - ElementId elementId = elementIdGuidPair.Value; - if (elementId == ElementId.InvalidElementId) - { - Importer.TheLog.LogError(-1, "Invalid Element ID found during Hybrid IFC Import Map construction.", false); - } - try - { - HybridMap.Add(ifcGuid, elementId); - } - catch (ArgumentException) - { - Importer.TheLog.LogWarning(-1, "Duplicate IFC Global Ids. This will cause some IFC entities to fallback to Revit processing.", false); - } - catch (Exception) - { - Importer.TheLog.LogWarning(-1, "Error in adding items to IFC GUID-to-ElementId map. This will cause some IFC entities to fallback to Revit processing.", false); - } - } - return HybridMap?.Count; - } - - /// - /// Replaces ElementIds in both Hybrid Element list and Hybrid Map (IfcGuid->ElementId) - /// - /// GUID of IFC entity. - /// Old ElementId to replace. - /// New ElementId to replace old ElementId with. - public void ReplaceElementId(string ifcGuid, ElementId oldElementId, ElementId newElementId) - { - if ((oldElementId == ElementId.InvalidElementId) || (newElementId == ElementId.InvalidElementId)) - return; - - // Reassign in HybridElements. - int index = HybridElements.IndexOf(oldElementId); - if (index == -1) - { - Importer.TheLog.LogWarning(-1, $"Unable to replace {ifcGuid} ElementId in list of Hybrid Elements.", true); - return; - } - - HybridElements[index] = newElementId; - - // Reassign in HybridMap if it exists. - if (!HybridMap.ContainsKey(ifcGuid)) - { - Importer.TheLog.LogWarning(-1, $"Unable to replace {ifcGuid} ElementId in Map of IFCGuids to ElementIds.", true); - return; - } - HybridMap[ifcGuid] = newElementId; - } - - /// - /// Creates a DirectShape simply to contain Geometry copied from other Elements. - /// The DirectShape won't have any Geometry at this time, but it will be put into the HybridMap. - /// - /// IfcProduct entity corresponding to empty DirectShape. - /// ElementId of new DirectShape if successful, ElementId.InvalidElementId otherwise. - public ElementId CreateEmptyContainer(IFCProduct ifcProduct) - { - // If HybridMap is null or empty, no other Elements were imported using the ATF Pipeline, so this doesn't need to be created. - if ((ifcProduct == null) || ((HybridMap?.Count ?? 0) == 0)) - { - return ElementId.InvalidElementId; - } - - // If Container is already in HybridMap, DirectShape has already been created. - ElementId containerElementId; - if (HybridMap.TryGetValue(ifcProduct.GlobalId, out containerElementId)) - { - return containerElementId; - } - - DirectShape emptyContainerDS = IFCElementUtil.CreateElement(IfcDocument, ifcProduct.GetCategoryId(IfcDocument), - ifcProduct.GlobalId, null, ifcProduct.Id, ifcProduct.EntityType); - if (emptyContainerDS == null) - { - return ElementId.InvalidElementId; - } - - HybridMap.Add(ifcProduct.GlobalId, emptyContainerDS.Id); - - return emptyContainerDS.Id; - } - /// /// This will create a container DirectShape to represent an IFCGroup, which normally has neither geometry /// nor a Revit Element associated with it. @@ -498,8 +318,8 @@ public ElementId CreateContainer(IFCGroup ifcGroup) { if (ifcGroup.ContainerFilteredEntity(objectDefinition)) { - ElementId objDefId = ElementId.InvalidElementId; - if (HybridMap?.TryGetValue(objectDefinition.GlobalId, out objDefId) ?? false) + ElementId objDefId = IFCImportHybridInfo.GetHybridMapInformation(objectDefinition.Id); + if (IFCImportHybridInfo.IsValidElementId(objDefId)) { elements.Add(objDefId); } @@ -527,7 +347,7 @@ public ElementId CreateContainer(IFCGroup ifcGroup) /// Entity that may exhibit special-case behavior. /// The element id of the existing DirectShape. /// ElementId of new DirectShape if new Element created, ElementId.InvalidElement otherwise. - private void UpdateElementForSpecialCases(IFCObjectDefinition objectDefinition, ref ElementId hybridElementId) + private void UpdateElementForSpecialCases(IFCObjectDefinition objectDefinition, ElementId hybridElementId) { if (objectDefinition == null) { @@ -540,23 +360,7 @@ private void UpdateElementForSpecialCases(IFCObjectDefinition objectDefinition, { if (objectDefinition is IFCProduct architecturalColumn) { - try - { - UpdateStructuralColumnDirectShape(architecturalColumn, hybridElementId); - } - catch (MissingMethodException) - { - ElementId specialCaseElementId = CreateStructuralColumnDirectShape(architecturalColumn, hybridElementId); - - if ((specialCaseElementId != ElementId.InvalidElementId) && (specialCaseElementId != hybridElementId)) - { - ElementId hybridElementIdToDelete = new ElementId(hybridElementId.Value); - // specialCaseElementId has replaced hybridElementId in the HybridMap. - // The hybridElementId will be deleted later. - Importer.TheHybridInfo.ElementsToDelete.Add(hybridElementIdToDelete); - hybridElementId = specialCaseElementId; - } - } + UpdateStructuralColumnDirectShape(architecturalColumn, hybridElementId); } } } @@ -595,11 +399,6 @@ private void UpdateStructuralColumnDirectShape(IFCProduct ifcColumn, ElementId h return; } - //IFC Extension back-compatibility: - //ImporterIFCUtils.UpdateDirectShapeCategory method available since Revit 2024.1, handle it for addin usage with the previous Revit versions. - //Handle this with using CreateStructuralColumnDirectShape instead by catching MissingMethodExseption in UpdateElementForSpecialCases. - // - ImporterIFCUtils.UpdateDirectShapeCategory(directShape, new ElementId(BuiltInCategory.OST_StructuralColumns)); (IList newGeomObjects, ElementId directShapeTypeId) = @@ -630,80 +429,6 @@ private void UpdateStructuralColumnDirectShape(IFCProduct ifcColumn, ElementId h directShape.SetTypeId(directShapeGeomTypeId); } - /// - /// Create a new DirectShape for the new Structural Column. - /// - /// - /// Column that needs a Category change from OST_Column to OST_StructuralColumn. - /// ElementId of new Structural Column for successful creation, ElementId.InvalidElementId otherwise. - private ElementId CreateStructuralColumnDirectShape(IFCProduct ifcColumn, ElementId hybridElementId) - { - if (ifcColumn == null) - { - Importer.TheLog.LogError(-1, "IfcColumn invalid during DirectShape recategorization.", false); - return ElementId.InvalidElementId; - } - - int stepId = ifcColumn.Id; - ElementId ifcColumnCategory = ifcColumn.GetCategoryId(IfcDocument); - if (ifcColumnCategory != new ElementId(BuiltInCategory.OST_StructuralColumns)) - { - Importer.TheLog.LogWarning(stepId, "IfcColumn is not a Structural Column", false); - return ElementId.InvalidElementId; - } - - DirectShape oldDirectShape = IfcDocument.GetElement(hybridElementId) as DirectShape; - ElementId oldDirectShapeCategory = (oldDirectShape?.Category?.Id ?? ElementId.InvalidElementId); - if (oldDirectShapeCategory == ElementId.InvalidElementId) - { - Importer.TheLog.LogWarning(stepId, "Unable to determine Category of DirectShape.", false); - return ElementId.InvalidElementId; - } - - if (oldDirectShapeCategory == ifcColumnCategory) - { - Importer.TheLog.LogComment(stepId, "Category of Column and DirectShape agree. No recategorization needed.", false); - return ElementId.InvalidElementId; - } - - // Perform Deep copy of Geometry and DirectShapeTypes. - (IList newGeomObjects, ElementId directShapeTypeId) - = DuplicateGeometryForDirectShape(oldDirectShape, ifcColumn); - if ((newGeomObjects?.Count ?? 0) == 0) - { - Importer.TheLog.LogError(stepId, "Unable to duplicate Geometry for DirectShape recategorization.", false); - return ElementId.InvalidElementId; - } - - GeometryInstance newDirectShapeGeometryInstance = newGeomObjects.First() as GeometryInstance; ; - if (newDirectShapeGeometryInstance == null) - { - Importer.TheLog.LogWarning(stepId, "Duplicate Geometry is not a GeometryInstance. Using old Geometry.", false); - return ElementId.InvalidElementId; - } - - directShapeTypeId = newDirectShapeGeometryInstance.GetSymbolGeometryId().SymbolId; - if (directShapeTypeId == ElementId.InvalidElementId) - { - Importer.TheLog.LogWarning(stepId, "Even though new DirectShape Geometry created, unable to find DirectShapeType.", false); - return ElementId.InvalidElementId; - } - - IList structuralColumnGeometry = new List() { newDirectShapeGeometryInstance }; - - DirectShape newDirectShape = IFCElementUtil.CreateElement(IfcDocument, ifcColumnCategory, ifcColumn.GlobalId, structuralColumnGeometry, stepId, ifcColumn.EntityType); - if (newDirectShape == null) - { - Importer.TheLog.LogError(stepId, "Unable to create new DirectShape Element for Structural Column.", false); - return ElementId.InvalidElementId; - } - - newDirectShape.SetTypeId(directShapeTypeId); - return newDirectShape.Id; - } - - - /// /// Duplicates Geometry within DirectShape for a new DirectShape creation. /// This is to drive the process where the DirectShape -> GInstance -> DirectShapeType -> etc. will be preserved. @@ -763,7 +488,7 @@ private GeometryInstance GetDirectShapeGeometryInstance(DirectShape directShape) } // Most of the work happens here to Copy DirectShapeTypes. - ElementId newDirectShapeTypeId = DeepCopyDirectShapeType(oldDirectShapeTypeElementId, + ElementId newDirectShapeTypeId = DeepCopyDirectShapeType(oldDirectShapeTypeElementId, oldDirectShapeTypeGeometryElement, ifcProduct.GetCategoryId(IfcDocument), ifcTypeObject); string definitionId = GetDirectShapeTypeDefinitionId(newDirectShapeTypeId); @@ -809,7 +534,7 @@ protected static string GetDirectShapeTypeDefinitionId(ElementId elementId) /// Category that DirectShapeTypes should be. /// IFCTypeObject step that drives this. If null, values from old DirectShapeType will be used. /// ElementId of new DirectShapeType, or ElementId.Invalid if unable to create new DirectShapeType at any step. - protected ElementId DeepCopyDirectShapeType(ElementId oldDirectShapeTypeElementId, GeometryElement oldDirectShapeTypeGeometryElement, + protected ElementId DeepCopyDirectShapeType(ElementId oldDirectShapeTypeElementId, GeometryElement oldDirectShapeTypeGeometryElement, ElementId newCategoryId, IFCTypeObject ifcTypeObject = null) { if ((oldDirectShapeTypeElementId == ElementId.InvalidElementId) || (oldDirectShapeTypeGeometryElement == null)) @@ -955,7 +680,7 @@ public IList DuplicateDirectShapeGeometry(IList direc { continue; } - + foreach (GeometryObject geometryObject in geometryElement) { // For Hybrid IFC Import, it is sufficient to check for GeometryInstances only. @@ -982,16 +707,14 @@ public IList DuplicateDirectShapeGeometry(IList direc /// But there are some data within Representation Items that need to persist to the new DirectShapes, and the only way to get that is to process the ProductRepresentation within the IFCProduct. /// So this populates that data. /// - /// Some data is contained in the ShapeEditScope (but not actual geometry). /// IFCProduct to edit. /// The associated element id. /// The list of created geometries. - public IList HandleHybridProductCreation(IFCImportShapeEditScope shapeEditScope, - IFCProduct ifcProduct, ref ElementId hybridElementId) + public IList HandleHybridProductCreation(IFCProduct ifcProduct, ElementId hybridElementId) { IList createdGeometries = new List(); - if (!Importer.TheOptions.IsHybridImport || (shapeEditScope == null) || (ifcProduct == null) || (hybridElementId == ElementId.InvalidElementId)) + if (!Importer.TheOptions.IsHybridImport || (ifcProduct == null) || (hybridElementId == ElementId.InvalidElementId)) { return createdGeometries; } @@ -1003,59 +726,25 @@ public IList DuplicateDirectShapeGeometry(IList direc return createdGeometries; } - // Get solids for IFCProduct. Only Points and Curves should be contained within "Solids". - if (ifcProduct.Solids?.Count > 0) - { - WireframeBuilder wireframeBuilder = new WireframeBuilder(); - foreach (IFCSolidInfo solidInfo in ifcProduct.Solids) - { - GeometryObject currObject = solidInfo.GeometryObject; - if (currObject is Point) - { - wireframeBuilder.AddPoint(currObject as Point); - } - else if (currObject is Curve) - { - wireframeBuilder.AddCurve(currObject as Curve); - } - else - { - continue; - } - createdGeometries.Add(currObject); - } - - directShape.AppendShape(wireframeBuilder); - } - - // Add Plan View Curves. - if (shapeEditScope.AddPlanViewCurves(ifcProduct.FootprintCurves, ifcProduct.Id)) - { - shapeEditScope.SetPlanViewRep(directShape); - } - - // IFCProduct needs PresentationLayer parameter, which is contained in the RepresentationItem (or IFCHybridRepresentationItem). - ifcProduct.PresentationLayerNames.UnionWith(shapeEditScope.PresentationLayerNames); - // Handle Special Cases: // 1. Possible Category Change for Structural Columns. This requires a whole new DirectShape/DirectShapeType tree creation. // 2. Containers for IfcRelAggregates (e.g., IfcWall & IfcBuildingElementParts). - Importer.TheHybridInfo.UpdateElementForSpecialCases(ifcProduct, ref hybridElementId); + Importer.TheHybridInfo.UpdateElementForSpecialCases(ifcProduct, hybridElementId); return createdGeometries; } /// - /// Adds IFCTypeObject GUID and DirectShapeType ElementId to HybridMap. + /// Adds IFCTypeObject STEP Id and DirectShapeType ElementId to HybridMap. /// /// /// Parameter 1: corresponds to DirectShape/IfcProduct. /// Parameter 2: corresponds to DirectShapeType/IfcTypeProduct. /// - /// Guid of IFCObject corresponding to DirectShape Element. + /// ElementId of DirectShape corresponding to IFCObject corresponding to this IFCTypeObject. /// Handle for IFCTypeObject. - public void AddTypeToHybridMap (string ifcObjectGuid, IFCAnyHandle ifcTypeObject) + public void AddTypeToHybridMap(ElementId directShapeElementId, IFCAnyHandle ifcTypeObject) { - if (string.IsNullOrEmpty(ifcObjectGuid)) + if (directShapeElementId == ElementId.InvalidElementId) return; if (IFCAnyHandleUtil.IsNullOrHasNoValue(ifcTypeObject)) @@ -1064,32 +753,72 @@ public void AddTypeToHybridMap (string ifcObjectGuid, IFCAnyHandle ifcTypeObject return; } - if (HybridMap == null) - { - Importer.TheLog.LogError(ifcTypeObject.Id, "HybridMap is null while trying to process IFCTypeObject for IFCObject. This shouldn't happen", true); + ElementId hybridElementId = IFCImportHybridInfo.GetHybridMapInformation(ifcTypeObject.Id); + if ((hybridElementId == null) || (hybridElementId != ElementId.InvalidElementId)) return; - } - string ifcTypeObjectGuid = IFCImportHandleUtil.GetRequiredStringAttribute(ifcTypeObject, "GlobalId", false); - if ((string.IsNullOrEmpty(ifcTypeObjectGuid)) || HybridMap.ContainsKey(ifcTypeObjectGuid)) - { - Importer.TheLog.LogComment(ifcTypeObject.Id, $"Already added IFC GUID {ifcTypeObjectGuid} to HybridMap. Not an error.", true); + DirectShape directShape = IfcDocument.GetElement(directShapeElementId) as DirectShape; + if (directShape == null) return; + + ElementId directShapeTypeElementId = directShape.TypeId; + if (directShapeTypeElementId != ElementId.InvalidElementId) + { + HybridMap.Add(ifcTypeObject.StepId.ToString(), directShapeTypeElementId); } + } + + /// + /// Indicates if indicated Element is a DirectShape, meaning it has usable Hybrid-imported Geometry. + /// + /// ElementId representing DirectShape. + /// True if a DirectShape, False otherwise. + public bool IsValidDirectShape(ElementId directShapeElementId) + { + return IfcDocument?.GetElement(directShapeElementId) is DirectShape; + } - ElementId directShapeElementId = ElementId.InvalidElementId; - if (HybridMap.TryGetValue(ifcObjectGuid, out directShapeElementId)) + /// + /// Retrieves the ElementId for an IFC entity, based on the STEP Id of the entity. + /// + /// STEP Id of the IFC entity. + /// ElementId of the IFC entity, or ElementId.InvalidElementId if not in the HybridMap, or null if Hybrid IFC Import not running. + public static ElementId GetHybridMapInformation(int stepId) + { + if (!Importer.TheOptions.IsHybridImport || Importer.TheHybridInfo?.HybridMap == null || (stepId <= 0)) + return null; + + string stepIdAsString = stepId.ToString(); + if (Importer.TheHybridInfo.HybridMap.TryGetValue(stepIdAsString, out ElementId hybridElementId)) { - DirectShape directShape = IfcDocument.GetElement(directShapeElementId) as DirectShape; - if (directShape == null) - return; + return hybridElementId; + } - ElementId directShapeTypeElementId = directShape.TypeId; - if (directShapeTypeElementId != ElementId.InvalidElementId) - { - HybridMap.Add(ifcTypeObjectGuid, directShapeTypeElementId); - } + return ElementId.InvalidElementId; + } + + /// + /// Retrieves the ElementId for an IFC entity, based on the STEP Id of the entity. + /// + /// Handle representing IFC entity./param> + /// ElementId of the IFC entity, or ElementId.InvalidElementId if not in the HybridMap, or null if Hybrid IFC Import not running. + + public static ElementId GetHybridMapInformation(IFCAnyHandle ifcEntity) + { + if (IFCAnyHandleUtil.IsNullOrHasNoValue(ifcEntity)) + { + Importer.TheLog.LogError(-1, "Hybrid IFC Import: attempting to retrieve invalid Entity from HybridMap", true); + return null; } + + return GetHybridMapInformation(ifcEntity.StepId); } + + /// + /// Simple helper function to check for Invalid ElementIds. + /// + /// ElementId for comparison. + /// True if elementId is non-null and not ElementId.InvalidElementId. + public static bool IsValidElementId(ElementId elementId) => ((elementId != null) && (elementId != ElementId.InvalidElementId)); } } diff --git a/Source/Revit.IFC.Import/Utility/IFCImportOptions.cs b/Source/Revit.IFC.Import/Utility/IFCImportOptions.cs index 999e7e1d..6a1c0a73 100644 --- a/Source/Revit.IFC.Import/Utility/IFCImportOptions.cs +++ b/Source/Revit.IFC.Import/Utility/IFCImportOptions.cs @@ -209,7 +209,7 @@ protected IFCImportOptions() { } - protected IFCImportOptions(IDictionary options, string ifcFileName, Document doc) + protected IFCImportOptions(IDictionary options) { // "Intent": covers what the import operation is intended to create. // The two options are: @@ -319,22 +319,11 @@ protected IFCImportOptions(IDictionary options, string ifcFileNa ImportIFCOptions importIFCOptions = ImportIFCOptions.GetImportIFCOptions(); string linkProcessor = importIFCOptions.LinkProcessor; - string revitVersion = doc.Application.VersionBuild; - if (revitVersion.StartsWith("24.0")) - { - // For Revit 24.0.x, only use hybrid import if revit.ini has "AnyCAD" set. - IsHybridImport = (string.Compare(linkProcessor, "AnyCAD", true) == 0) && - (ifcFileName.EndsWith(".ifc")) && (Processor is IFCDefaultProcessor); - } - else - { - // For Revit 24.1.x - // Use hybrid import if revit.ini does not have "Legacy" in it and we are using - // the default (Revit) processor. For other processors (e.g., Navis), revert - // to Legacy. - IsHybridImport = (string.Compare(linkProcessor, "Legacy", true) != 0) && - (Processor is IFCDefaultProcessor); - } + // Use hybrid import if revit.ini does not have "Legacy" in it and we are using + // the default (Revit) processor. For other processors (e.g., Navis), revert + // to Legacy. + IsHybridImport = (string.Compare(linkProcessor, "Legacy", true) != 0) && + (Processor is IFCDefaultProcessor); } /// @@ -342,9 +331,9 @@ protected IFCImportOptions(IDictionary options, string ifcFileNa /// /// The user-set options for this import. /// The new IFCImportOptions class. - static public IFCImportOptions Create(IDictionary options, string ifcFileName, Document doc) + static public IFCImportOptions Create(IDictionary options) { - return new IFCImportOptions(options, ifcFileName, doc); + return new IFCImportOptions(options); } } } \ No newline at end of file diff --git a/Source/Revit.IFC.Import/Utility/ParametersToSet.cs b/Source/Revit.IFC.Import/Utility/ParametersToSet.cs index b5d00939..d9712b06 100644 --- a/Source/Revit.IFC.Import/Utility/ParametersToSet.cs +++ b/Source/Revit.IFC.Import/Utility/ParametersToSet.cs @@ -17,57 +17,10 @@ public void Dispose() { if (ParametersToSet != null) { - //IFC Extension back - compatibility: - //Parameter.SetMultiple method available since Revit 2024.1, handle it for addin usage with the previous Revit versions. - // - try - { - TryToSetMultipleParameters(); - } - catch (MissingMethodException) - { - foreach (Tuple parameterAndParameterValue in ParametersToSet.ParameterList) - { - Parameter param = parameterAndParameterValue.Item1; - ParameterValue paramValue = parameterAndParameterValue.Item2; - - if(param != null) - { - StorageType storageType = param.StorageType; - switch (storageType) - { - case StorageType.Integer: - { - param.Set((int)(paramValue as IntegerParameterValue)?.Value); - break; - } - case StorageType.Double: - { - param.Set((double)(paramValue as DoubleParameterValue)?.Value); - break; - } - case StorageType.String: - { - param.Set((string)(paramValue as StringParameterValue)?.Value); - break; - } - case StorageType.ElementId: - { - param.Set((ElementId)(paramValue as ElementIdParameterValue)?.Value); - break; - } - } - } - } - } + Parameter.SetMultiple(ParametersToSet.ParameterList); } } - private void TryToSetMultipleParameters() - { - Parameter.SetMultiple(ParametersToSet.ParameterList); - } - public ParametersToSet ParametersToSet { get; private set; } = null; } diff --git a/Source/Revit.IFC.Import/Utility/ProcessIFCRelation.cs b/Source/Revit.IFC.Import/Utility/ProcessIFCRelation.cs index 9399147e..ddb74409 100644 --- a/Source/Revit.IFC.Import/Utility/ProcessIFCRelation.cs +++ b/Source/Revit.IFC.Import/Utility/ProcessIFCRelation.cs @@ -108,28 +108,6 @@ static public ICollection ProcessRelatedObjects(IFCObjectDe } } - if (Importer.TheOptions.IsHybridImport && Importer.TheHybridInfo != null && - IFCAnyHandleUtil.IsTypeOf(ifcRelAssignsOrAggregates, IFCEntityType.IfcRelAggregates) && - (relatedTo is IFCElement ifcElementRelatedTo)) - { - if (Importer.TheHybridInfo.ContainerMap == null) - { - Importer.TheHybridInfo.ContainerMap = new Dictionary>(); - } - - HashSet containedObjectDefinitions = null; - if (Importer.TheHybridInfo.ContainerMap.TryGetValue(ifcElementRelatedTo.Id, out containedObjectDefinitions)) - { - containedObjectDefinitions.UnionWith(relatedObjectSet); - } - else - { - containedObjectDefinitions = new HashSet(); - containedObjectDefinitions.UnionWith(relatedObjectSet); - Importer.TheHybridInfo.ContainerMap.Add(ifcElementRelatedTo.Id, containedObjectDefinitions); - } - } - return relatedObjectSet; } diff --git a/Source/RevitIFCTools/IFCEntityListWin.xaml.cs b/Source/RevitIFCTools/IFCEntityListWin.xaml.cs index feea2d67..3a7f1216 100644 --- a/Source/RevitIFCTools/IFCEntityListWin.xaml.cs +++ b/Source/RevitIFCTools/IFCEntityListWin.xaml.cs @@ -463,9 +463,9 @@ private void Button_ExportInfoPair_Click(object sender, RoutedEventArgs e) if (!Enum.TryParse(entity, out entType)) return; - exportInfo.SetValueWithPair(entType, predefType); + exportInfo.SetByTypeAndPredefinedType(entType, predefType); textBox_type2.Text = "Instance: " + exportInfo.ExportInstance + "\nType: " + exportInfo.ExportType - + "\r\nPredefinedTpe: " + exportInfo.ValidatedPredefinedType; + + "\r\nPredefinedTpe: " + exportInfo.PredefinedType; } } } diff --git a/Source/RevitIFCTools/MainWindow.xaml.cs b/Source/RevitIFCTools/MainWindow.xaml.cs index 44966fe1..0ab44350 100644 --- a/Source/RevitIFCTools/MainWindow.xaml.cs +++ b/Source/RevitIFCTools/MainWindow.xaml.cs @@ -19,6 +19,7 @@ using System; using System.Windows; +using RevitIFCTools.ParameterExpr; namespace RevitIFCTools { @@ -51,7 +52,7 @@ private void button_Cancel_Click(object sender, RoutedEventArgs e) private void button_paramexpr_Click(object sender, RoutedEventArgs e) { - ParameterExpr.ExprTester exprTest = new ParameterExpr.ExprTester(); + ExprTester exprTest = new ParameterExpr.ExprTester(); exprTest.ShowDialog(); } diff --git a/Source/RevitIFCTools/Properties/AssemblyInfo.cs b/Source/RevitIFCTools/Properties/AssemblyInfo.cs index d4fa2d58..71caca56 100644 --- a/Source/RevitIFCTools/Properties/AssemblyInfo.cs +++ b/Source/RevitIFCTools/Properties/AssemblyInfo.cs @@ -12,7 +12,7 @@ [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Autodesk")] [assembly: AssemblyProduct("RevitIFCTools")] -[assembly: AssemblyCopyright("Copyright © 2012-2022")] +[assembly: AssemblyCopyright("Copyright © 2012-2024")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -51,5 +51,6 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("24.2.0.49")] -[assembly: AssemblyFileVersion("24.2.0.49")] +[assembly: System.Runtime.Versioning.SupportedOSPlatformAttribute("windows7.0")] +[assembly: AssemblyVersion("25.2.0.0")] +[assembly: AssemblyFileVersion("25.2.0.0")] \ No newline at end of file diff --git a/Source/RevitIFCTools/Properties/Resources.Designer.cs b/Source/RevitIFCTools/Properties/Resources.Designer.cs index 2114038e..5a9c312d 100644 --- a/Source/RevitIFCTools/Properties/Resources.Designer.cs +++ b/Source/RevitIFCTools/Properties/Resources.Designer.cs @@ -19,7 +19,7 @@ namespace RevitIFCTools.Properties { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { diff --git a/Source/RevitIFCTools/RevitIFCTools.csproj b/Source/RevitIFCTools/RevitIFCTools.csproj index 633a7d39..e4e19605 100644 --- a/Source/RevitIFCTools/RevitIFCTools.csproj +++ b/Source/RevitIFCTools/RevitIFCTools.csproj @@ -1,228 +1,48 @@ - - - + - Debug - x64 - {FFD592F6-DB2C-4E5D-9C38-9CCC9EABB3EA} - WinExe - Properties RevitIFCTools RevitIFCTools - v4.8 - 512 - {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - 4 - true - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true - - - - - - true - bin\Debugx64\ - TRACE;DEBUG;OVERRIDE_VERSION;IFC_OPENSOURCE - full - x64 - 7.3 - prompt - - - bin\Releasex64\ - TRACE;IFC_OPENSOURCE - true - pdbonly - x64 - 7.3 - prompt + WinExe + true + false + False + - - ..\..\..\..\Program Files\Autodesk\Revit 2024\RevitAPI.dll - - - - - - - - - - - - - 4.0 - - - - - - - - MSBuild:Compile - Designer - - - - ExprTester.xaml - - - - - - - - - - - - - - - - - - - - MSBuild:Compile - Designer - - - App.xaml - Code - - - IFCEntityListWin.xaml - Code - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - - - GeneratePsetDefWin.xaml - - - MainWindow.xaml - - - Code - - - True - True - Resources.resx - - - True - Settings.settings - True - - - ResXFileCodeGenerator - Resources.Designer.cs - - - PreserveNewest - - - Designer - PreserveNewest - - - PreserveNewest - - - Designer - PreserveNewest - - - PreserveNewest - - - Designer - PreserveNewest - - - PreserveNewest - - - SettingsSingleFileGenerator - Settings.Designer.cs - - + + + + + - - - - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - + + + + + - - + + + + + + + ..\..\..\..\Program Files\Autodesk\Revit 2025\RevitAPI.dll + + + + + 4.6.6 - - - {032ea4dc-181f-4453-9f93-e08de1c07d95} - Revit.IFC.Common - - - {bce5141a-291b-4cd8-a69b-7b9345aa00e9} - Revit.IFC.Export - - - - - xcopy "$(TargetPath)" "C:\ProgramData\Autodesk\ApplicationPlugins\IFC 2024.bundle\Contents\2024\" /F /R /Y /I -xcopy "$(TargetDir)IFC*.xsd" "C:\ProgramData\Autodesk\ApplicationPlugins\IFC 2024.bundle\Contents\2024\" /F /R /Y /I -xcopy "$(TargetDir)IFC*.exp" "C:\ProgramData\Autodesk\ApplicationPlugins\IFC 2024.bundle\Contents\2024\" /F /R /Y /I -xcopy "$(TargetDir)IFC Shared Parameters*.txt" "C:\ProgramData\Autodesk\ApplicationPlugins\IFC 2024.bundle\Contents\2024\" /F /R /Y /I -xcopy "$(TargetDir)IFCCertifiedEntitiesAndPSets.json" "C:\ProgramData\Autodesk\ApplicationPlugins\IFC 2024.bundle\Contents\2024\" /F /R /Y /I - - - + + + + + + + + + \ No newline at end of file diff --git a/Source/ThirdParty/ICSharpCode/ICSharpCode.SharpZipLib.DLL b/Source/ThirdParty/ICSharpCode/ICSharpCode.SharpZipLib.DLL index 8cc48486c82922ec88831eb1801df33be15038f3..08de420a696cc1a704f4992da302d124d3e7e100 100644 GIT binary patch literal 258048 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 E3X+t({{R30 literal 212552 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 Bqf`I@ diff --git a/VSProps/Revit.CSharp.Sdk.props b/VSProps/Revit.CSharp.Sdk.props new file mode 100644 index 00000000..41952d36 --- /dev/null +++ b/VSProps/Revit.CSharp.Sdk.props @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/VSProps/Revit.CSharp.Sdk.targets b/VSProps/Revit.CSharp.Sdk.targets new file mode 100644 index 00000000..23a97a1b --- /dev/null +++ b/VSProps/Revit.CSharp.Sdk.targets @@ -0,0 +1,21 @@ + + + TRACE;$(DefineConstants) + + + TRACE;$(DefineConstants) + + + DEBUG;TRACE;$(DefineConstants) + + + 7 + + + + + + $(MSBuildAllProjects);$(SolutionDir)VSProps\Revit.CSharp.Sdk.targets + + diff --git a/VSProps/Revit.Common.Sdk.props b/VSProps/Revit.Common.Sdk.props new file mode 100644 index 00000000..97eb17eb --- /dev/null +++ b/VSProps/Revit.Common.Sdk.props @@ -0,0 +1,40 @@ + + + + x64 + Debug;Release;Slow_Debug + Debug + x64 + $(SolutionDir)\Intermediate\$(Configuration)$(Platform)\$(MSBuildProjectName)\ + $(BaseIntermediateOutputPath) + false + false + false + x64 + true + true + true + false + true + true + + + + x64 + x64\Release + Release + + + + x64 + x64\Release + Release + + + + x64 + x64\Debug + Debug + d + + diff --git a/VSProps/Revit.Common.Sdk.targets b/VSProps/Revit.Common.Sdk.targets new file mode 100644 index 00000000..f01f9c6d --- /dev/null +++ b/VSProps/Revit.Common.Sdk.targets @@ -0,0 +1,37 @@ + + + + + Code + + + + + x64 + Airmax2016 + true + full + true + 4 + 1668 + + + false + x64\Release + + + true + x64\Release + + + false + x64\Debug + + + 1607 + + + $(MSBuildAllProjects);$(SolutionDir)VSProps\Revit.Common.Sdk.targets + + + diff --git a/VSProps/Revit.NetVersion.props b/VSProps/Revit.NetVersion.props new file mode 100644 index 00000000..d711542d --- /dev/null +++ b/VSProps/Revit.NetVersion.props @@ -0,0 +1,6 @@ + + + + net8.0-windows + + From f0d013026f0028fc90aa83d67437c796d7f4a1e1 Mon Sep 17 00:00:00 2001 From: mostafa901 Date: Fri, 14 Jun 2024 22:32:11 +0200 Subject: [PATCH 2/4] fix-Export-linked-file-using-api --- .../IFCCommandOverrideApplication.cs | 412 +------------ .../IFCExportConfiguration.cs | 11 +- .../IFCLinkedDocumentExporter.cs | 572 ++++++++++++++++++ 3 files changed, 588 insertions(+), 407 deletions(-) create mode 100644 Source/IFCExporterUIOverride/IFCLinkedDocumentExporter.cs diff --git a/Source/IFCExporterUIOverride/IFCCommandOverrideApplication.cs b/Source/IFCExporterUIOverride/IFCCommandOverrideApplication.cs index 6f9c9001..4b012421 100644 --- a/Source/IFCExporterUIOverride/IFCCommandOverrideApplication.cs +++ b/Source/IFCExporterUIOverride/IFCCommandOverrideApplication.cs @@ -289,56 +289,11 @@ public void OnIFCExport(object sender, CommandEventArgs args) selectedConfig.ActiveViewId = selectedConfig.UseActiveViewGeometry ? activeViewId : ElementId.InvalidElementId; selectedConfig.UpdateOptions(exportOptions, activeViewId); - IDictionary linkGUIDsCache = - new Dictionary(); - - IDictionary linkInstanceTranforms = null; - string errorMessage = null; - int numBadInstances = 0; - + IFCLinkedDocumentExporter linkExporter = null; if (exportLinks) { - // Cache for links guids - FilteredElementCollector collector = new FilteredElementCollector(document); - ElementFilter elementFilter = new ElementClassFilter(typeof(RevitLinkInstance)); - List rvtLinkInstances = - collector.WherePasses(elementFilter).Cast().ToList(); - - string linkGuidOptionString = string.Empty; - - // Get the transforms of the links we can export, and error message information, - // including number, for the ones we can't. - (linkInstanceTranforms, errorMessage, numBadInstances) = - GetLinkedInstanceInfo(rvtLinkInstances); - - ISet existingGUIDs = new HashSet(); - - foreach (RevitLinkInstance linkInstance in linkInstanceTranforms.Keys) - { - Parameter parameter = linkInstance.get_Parameter(BuiltInParameter.IFC_GUID); - - string sGUID = GUIDUtil.GetSimpleElementIFCGUID(linkInstance); - - string sGUIDlower = sGUID.ToLower(); - - while (existingGUIDs.Contains(sGUIDlower)) - { - sGUID += "-"; - sGUIDlower += "-"; - } - existingGUIDs.Add(sGUIDlower); - - if (doFederatedExport) - linkGuidOptionString += linkInstance.Id.ToString() + "," + sGUID + ";"; - else - linkGUIDsCache.Add(linkInstance.Id, sGUID); - } - - if (doFederatedExport) - { - exportOptions.AddOption("ExportingLinks", selectedConfig.ExportLinkedFiles.ToString()); - exportOptions.AddOption("FederatedLinkInfo", linkGuidOptionString); - } + linkExporter = new IFCLinkedDocumentExporter(document, exportOptions); + linkExporter.SetExportOption(selectedConfig.ExportLinkedFiles); } bool result = document.Export(path, fileName, exportOptions); @@ -357,27 +312,17 @@ public void OnIFCExport(object sender, CommandEventArgs args) // Export links as separate files if (exportSeparateLinks) { - // We can't use the FilterViewId for linked documents, because the - // intermediate code assumes that it is in the exported document. As such, - // we will pass it in a special place. - ElementId originalFilterViewId = exportOptions.FilterViewId; - if (originalFilterViewId != ElementId.InvalidElementId) - { - exportOptions.AddOption("HostViewId", exportOptions.FilterViewId.ToString()); - exportOptions.FilterViewId = ElementId.InvalidElementId; - } - ExportOptionsCache.HostDocument = document; - exportOptions.AddOption("ExportingLinks", LinkedFileExportAs.ExportAsSeparate.ToString()); - ExportLinkedDocuments(document, fullName, linkGUIDsCache, linkInstanceTranforms, - exportOptions, originalFilterViewId); + linkExporter.ExportSeparateDocuments(fullName); } + string errorMessage = linkExporter?.GetErrors(); + // Show user errors, if any. if (!string.IsNullOrEmpty(errorMessage)) { using (Autodesk.Revit.UI.TaskDialog taskDialog = new Autodesk.Revit.UI.TaskDialog(Properties.Resources.IFCExport)) { - taskDialog.MainInstruction = string.Format(Properties.Resources.LinkInstanceExportErrorMain, numBadInstances); + taskDialog.MainInstruction = string.Format(Properties.Resources.LinkInstanceExportErrorMain, linkExporter.GetNumberOfBadInstances()); taskDialog.MainIcon = Autodesk.Revit.UI.TaskDialogIcon.TaskDialogIconWarning; taskDialog.TitleAutoPrefix = false; @@ -419,348 +364,5 @@ public void OnIFCExport(object sender, CommandEventArgs args) } } } - - private string FileNameListToString(IList fileNames) - { - string fileNameListString = ""; - foreach (string fileName in fileNames) - { - if (fileNameListString != "") - fileNameListString += "; "; - fileNameListString += fileNames; - } - return fileNameListString; - } - - private string ElementIdListToString(IList elementIds) - { - string elementString = ""; - foreach (ElementId elementId in elementIds) - { - if (elementString != "") - elementString += ", "; - elementString += elementId.ToString(); - } - return elementString; - } - - // This modifies an existing string to display an expanded error message to the user. - private void AddExpandedStringContent(ref string messageString, string formatString, IList items) - { - if (messageString != "") - messageString += "\n"; - - if (items.Count > 0) - messageString += string.Format(formatString, FileNameListToString(items)); - } - - // This modifies an existing string to display an expanded error message to the user. - private void AddExpandedElementIdContent(ref string messageString, string formatString, IList items) - { - if (messageString != "") - messageString += "\n"; - - if (items.Count > 0) - messageString += string.Format(formatString, ElementIdListToString(items)); - } - - private string GetLinkFileName(Document linkDocument, string linkPathName) - { - int index = linkPathName.LastIndexOf("\\"); - if (index <= 0) - return linkDocument.Title; - - string linkFileName = linkPathName.Substring(index + 1); - // remove the extension - index = linkFileName.LastIndexOf('.'); - if (index > 0) - linkFileName = linkFileName.Substring(0, index); - return linkFileName; - } - - private (IDictionary, string, int) GetLinkedInstanceInfo( - IList linkInstances) - { - IDictionary linkedInstanceTransforms = - new SortedDictionary(new ElementComparer()); - - // We will keep track of the instances we can't export. - // Reasons we can't export: - // 1. Couldn't create a temporary document for exporting the linked instance. - // 2. The document for the linked instance can't be found. - // 3. The linked instance is mirrored, non-conformal, or scaled. - IList noTempDoc = new List(); - - IList nonConformalInst = new List(); - IList scaledInst = new List(); - IList instHasReflection = new List(); - - int numBadInstances = 0; - - foreach (RevitLinkInstance currRvtLinkInstance in linkInstances) - { - // Nothing to report if the element itself is null. - if (currRvtLinkInstance == null) - continue; - - // get the link document and the unit scale - Document linkDocument = currRvtLinkInstance.GetLinkDocument(); - if (linkDocument == null) - { - // We can't distinguish between unloaded and an error condition, so we - // won't get a likely extraneous error. - continue; - } - - double lengthScaleFactorLink = UnitUtils.ConvertFromInternalUnits( - 1.0, - linkDocument.GetUnits().GetFormatOptions(SpecTypeId.Length).GetUnitTypeId()); - - // get the link transform - Transform tr = currRvtLinkInstance.GetTransform(); - - // We can't handle non-conformal, scaled, or mirrored transforms. - ElementId instanceId = currRvtLinkInstance.Id; - if (!tr.IsConformal) - { - nonConformalInst.Add(instanceId); - numBadInstances++; - continue; - } - - if (tr.HasReflection) - { - instHasReflection.Add(instanceId); - numBadInstances++; - continue; - } - - if (!MathUtil.IsAlmostEqual(tr.Determinant, 1.0)) - { - scaledInst.Add(instanceId); - numBadInstances++; - continue; - } - - // scale the transform origin - tr.Origin *= lengthScaleFactorLink; - - linkedInstanceTransforms[currRvtLinkInstance] = tr; - } - - // Show user errors, if any. - string expandedContent = string.Empty; - AddExpandedStringContent(ref expandedContent, Properties.Resources.LinkInstanceExportCantCreateDoc, noTempDoc); - AddExpandedElementIdContent(ref expandedContent, Properties.Resources.LinkInstanceExportNonConformal, nonConformalInst); - AddExpandedElementIdContent(ref expandedContent, Properties.Resources.LinkInstanceExportScaled, scaledInst); - AddExpandedElementIdContent(ref expandedContent, Properties.Resources.LinkInstanceExportHasReflection, instHasReflection); - - return (linkedInstanceTransforms, expandedContent, numBadInstances); - } - - /// - /// Checks if element is visible for certain view. - /// - /// The element. - /// True if the element is visible, false otherwise. - public bool IsLinkVisible(Element element, View filterView) - { - if (filterView == null) - return true; - - if (element.IsHidden(filterView)) - return false; - - if (!(element.Category?.get_Visible(filterView) ?? false)) - return false; - - return filterView.IsElementVisibleInTemporaryViewMode(TemporaryViewMode.TemporaryHideIsolate, element.Id); - } - - public void ExportLinkedDocuments(Document document, string fileName, - IDictionary linkGUIDsCache, - IDictionary idToTransform, - IFCExportOptions exportOptions, ElementId originalFilterViewId) - { - // get the extension - int index = fileName.LastIndexOf('.'); - if (index <= 0) - return; - string sExtension = fileName.Substring(index); - fileName = fileName.Substring(0, index); - - // get all the revit link instances - IDictionary rvtLinkNamesDict = new Dictionary(); - IDictionary> rvtLinkNamesToInstancesDict = - new Dictionary>(); - - try - { - View filterView = document.GetElement(originalFilterViewId) as View; - foreach (RevitLinkInstance rvtLinkInstance in idToTransform.Keys) - { - if (!IsLinkVisible(rvtLinkInstance, filterView)) - continue; - - // get the link document - Document linkDocument = rvtLinkInstance.GetLinkDocument(); - if (linkDocument == null) - continue; - - // get the link file path and name - String linkPathName = ""; - Parameter originalFileNameParam = linkDocument.ProjectInformation.LookupParameter("Original IFC File Name"); - if (originalFileNameParam != null && originalFileNameParam.StorageType == StorageType.String) - linkPathName = originalFileNameParam.AsString(); - else - linkPathName = linkDocument.PathName; - - // get the link file name - string linkFileName = GetLinkFileName(linkDocument, linkPathName); - - // add to names count dictionary - if (!rvtLinkNamesDict.Keys.Contains(linkFileName)) - rvtLinkNamesDict.Add(linkFileName, 0); - rvtLinkNamesDict[linkFileName]++; - - // add to names instances dictionary - if (!rvtLinkNamesToInstancesDict.Keys.Contains(linkPathName)) - rvtLinkNamesToInstancesDict.Add(linkPathName, new List()); - rvtLinkNamesToInstancesDict[linkPathName].Add(rvtLinkInstance); - } - } - catch - { - } - - foreach (KeyValuePair> linkPathNames in rvtLinkNamesToInstancesDict) - { - string linkPathName = linkPathNames.Key; - - // get the link instances - List currRvtLinkInstances = rvtLinkNamesToInstancesDict[linkPathName]; - IList linkFileNames = new List(); - IList> serTransforms = new List>(); - - Document linkDocument = null; - - foreach (RevitLinkInstance currRvtLinkInstance in currRvtLinkInstances) - { - // Nothing to report if the element itself is null. - if (currRvtLinkInstance == null) - continue; - - ElementId instanceId = currRvtLinkInstance.Id; - - // get the link document and the unit scale - linkDocument = linkDocument ?? currRvtLinkInstance.GetLinkDocument(); - - // get the link file path and name - string linkFileName = GetLinkFileName(linkDocument, linkPathName); - - //if link was an IFC file then make a different formating to the file name - if ((linkPathName.Length >= 4 && linkPathName.Substring(linkPathName.Length - 4).ToLower() == ".ifc") || - (linkPathName.Length >= 7 && linkPathName.Substring(linkPathName.Length - 7).ToLower() == ".ifcxml") || - (linkPathName.Length >= 7 && linkPathName.Substring(linkPathName.Length - 7).ToLower() == ".ifczip")) - { - string fName = fileName; - - //get output path and add to the new file name - index = fName.LastIndexOf("\\"); - if (index > 0) - fName = fName.Substring(0, index + 1); - else - fName = ""; - - //construct IFC file name - linkFileName = fName + linkFileName + "-"; - - //add guid - linkFileName += linkGUIDsCache[instanceId]; - } - else - { - // check if there are multiple instances with the same name - bool bMultiple = (rvtLinkNamesDict[linkFileName] > 1); - - // add the path - linkFileName = fileName + "-" + linkFileName; - - // add the guid - if (bMultiple) - { - linkFileName += "-"; - linkFileName += linkGUIDsCache[instanceId]; - } - } - - // add the extension - linkFileName += sExtension; - - linkFileNames.Add(linkFileName); - - // serialize transform - serTransforms.Add(Tuple.Create(instanceId, SerializeTransform(idToTransform[currRvtLinkInstance]))); - } - - if (linkDocument != null) - { - // export - try - { - int numLinkInstancesToExport = linkFileNames.Count; - exportOptions.AddOption("NumberOfExportedLinkInstances", numLinkInstancesToExport.ToString()); - - for (int ind = 0; ind < numLinkInstancesToExport; ind++) - { - string optionName = (ind == 0) ? "ExportLinkId" : "ExportLinkId" + (ind + 1).ToString(); - exportOptions.AddOption(optionName, serTransforms[ind].Item1.ToString()); - - optionName = (ind == 0) ? "ExportLinkInstanceTransform" : "ExportLinkInstanceTransform" + (ind + 1).ToString(); - exportOptions.AddOption(optionName, serTransforms[ind].Item2); - - // Don't pass in file name for the first link instance. - if (ind == 0) - continue; - - optionName = "ExportLinkInstanceFileName" + (ind + 1).ToString(); - exportOptions.AddOption(optionName, linkFileNames[ind]); - } - - // Pass in the first value; the rest will be in the options. - string path_ = Path.GetDirectoryName(linkFileNames[0]); - string fileName_ = Path.GetFileName(linkFileNames[0]); - - // Normally, IFC export would need a transaction, even if no permanent - // changes are made. For linked documents, though, that's handled by the - // export itself. - using (IFCLinkDocumentExportScope scope = new IFCLinkDocumentExportScope(linkDocument)) - { - linkDocument.Export(path_, fileName_, exportOptions); - } - } - catch - { - } - } - } - } - - public static string SerializeXYZ(XYZ value) - { - //transform to string - return value.ToString(); - } - - public static string SerializeTransform(Transform tr) - { - string retVal = string.Empty; - //serialize the transform values - retVal += SerializeXYZ(tr.Origin) + ";"; - retVal += SerializeXYZ(tr.BasisX) + ";"; - retVal += SerializeXYZ(tr.BasisY) + ";"; - retVal += SerializeXYZ(tr.BasisZ) + ";"; - return retVal; - } } } \ No newline at end of file diff --git a/Source/IFCExporterUIOverride/IFCExportConfiguration.cs b/Source/IFCExporterUIOverride/IFCExportConfiguration.cs index e5effa31..fb329770 100644 --- a/Source/IFCExporterUIOverride/IFCExportConfiguration.cs +++ b/Source/IFCExporterUIOverride/IFCExportConfiguration.cs @@ -46,7 +46,7 @@ public static bool ConfigurationsAreEqual(T obj1, T obj2) DateFormatHandling = DateFormatHandling.MicrosoftDateFormat }; - var obj1Ser = JsonConvert.SerializeObject(obj1, settings); + var obj1Ser = JsonConvert.SerializeObject(obj1, settings); var obj2Ser = JsonConvert.SerializeObject(obj2, settings); return obj1Ser == obj2Ser; } @@ -642,6 +642,12 @@ public void UpdateBuiltInConfiguration(IFCExportConfiguration updatedConfig) } } + /// + /// Available after Calling public void UpdateOptions(IFCExportOptions options, ElementId filterViewId) + /// and LinkedFileExportAs should not be DontExport + /// + public IFCLinkedDocumentExporter LinkExporter { get; private set; } + /// /// Updates the IFCExportOptions with the settings in this configuration. /// @@ -650,7 +656,8 @@ public void UpdateBuiltInConfiguration(IFCExportConfiguration updatedConfig) public void UpdateOptions(IFCExportOptions options, ElementId filterViewId) { options.FilterViewId = VisibleElementsOfCurrentView ? filterViewId : ElementId.InvalidElementId; - + var linkExporter = ExportLinkedFiles == LinkedFileExportAs.DontExport ? null : new IFCLinkedDocumentExporter(IFCCommandOverrideApplication.TheDocument, options); + linkExporter?.SetExportOption(ExportLinkedFiles); foreach (var prop in GetType().GetProperties()) { switch (prop.Name) diff --git a/Source/IFCExporterUIOverride/IFCLinkedDocumentExporter.cs b/Source/IFCExporterUIOverride/IFCLinkedDocumentExporter.cs new file mode 100644 index 00000000..7c168d2c --- /dev/null +++ b/Source/IFCExporterUIOverride/IFCLinkedDocumentExporter.cs @@ -0,0 +1,572 @@ +// BIM IFC export alternate UI library: this library works with Autodesk(R) Revit(R) to provide an alternate user interface for the export of IFC +// files from Revit. Copyright (C) 2016 Autodesk, Inc. +// +// This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +namespace BIM.IFC.Export.UI +{ + using System; + using System.Collections.Generic; + using System.IO; + using System.Linq; + using Autodesk.Revit.DB; + using Autodesk.Revit.DB.IFC; + using Revit.IFC.Common.Utility; + using Revit.IFC.Export.Utility; + + /// + /// Defines the + /// + public class IFCLinkedDocumentExporter + { + + #region Private Fields + + /// + /// Defines the document + /// + private readonly Document document; + + /// + /// Defines the ifcOptions + /// + private readonly IFCExportOptions ifcOptions; + + /// + /// Gets or sets the ErrorMessage + /// + private string errorMessage = null; + + /// + /// Defines the numBadInstances + /// + private int numBadInstances = 0; + + #endregion Private Fields + + #region Internal Fields + + /// + /// Gets or sets the LinkGUIDsCache + /// + internal IDictionary linkGUIDsCache = + new Dictionary(); + + /// + /// Gets or sets the LinkInstanceTranforms + /// + internal IDictionary linkInstanceTranforms = null; + + #endregion Internal Fields + + #region Public Constructors + + /// + /// Initializes a new instance of the class. + /// + /// The document + /// The ifcOptions + public IFCLinkedDocumentExporter(Document document, IFCExportOptions ifcOptions) + { + this.document = document; + this.ifcOptions = ifcOptions; + } + + #endregion Public Constructors + + #region Private Methods + + /// + /// The SerializeTransform + /// + /// The tr + /// The + private static string SerializeTransform(Transform tr) + { + string retVal = string.Empty; + //serialize the transform values + retVal += SerializeXYZ(tr.Origin) + ";"; + retVal += SerializeXYZ(tr.BasisX) + ";"; + retVal += SerializeXYZ(tr.BasisY) + ";"; + retVal += SerializeXYZ(tr.BasisZ) + ";"; + return retVal; + } + + /// + /// The SerializeXYZ + /// + /// The value + /// The + private static string SerializeXYZ(XYZ value) + { + //transform to string + return value.ToString(); + } + + /// + /// The AddExpandedElementIdContent + /// + /// The messageString + /// The formatString + /// The items + private void AddExpandedElementIdContent(ref string messageString, string formatString, IList items) + { + if (messageString != "") + messageString += "\n"; + + if (items.Count > 0) + messageString += string.Format(formatString, ElementIdListToString(items)); + } + + /// + /// The AddExpandedStringContent + /// + /// The messageString + /// The formatString + /// The items + private void AddExpandedStringContent(ref string messageString, string formatString, IList items) + { + if (messageString != "") + messageString += "\n"; + + if (items.Count > 0) + messageString += string.Format(formatString, FileNameListToString(items)); + } + + // This modifies an existing string to display an expanded error message to the user. This modifies an existing string to display an expanded + // error message to the user. + /// + /// The ElementIdListToString + /// + /// The elementIds + /// The + private string ElementIdListToString(IList elementIds) + { + string elementString = ""; + foreach (ElementId elementId in elementIds) + { + if (elementString != "") + elementString += ", "; + elementString += elementId.ToString(); + } + return elementString; + } + + /// + /// The ExportLinkedDocuments + /// + /// The document + /// The fileName + /// The linkGUIDsCache + /// The idToTransform + /// The exportOptions + /// The originalFilterViewId + private void ExportLinkedDocuments(Document document, string fileName, + IDictionary linkGUIDsCache, + IDictionary idToTransform, + IFCExportOptions exportOptions, ElementId originalFilterViewId) + { + // get the extension + int index = fileName.LastIndexOf('.'); + if (index <= 0) + return; + string sExtension = fileName.Substring(index); + fileName = fileName.Substring(0, index); + + // get all the revit link instances + IDictionary rvtLinkNamesDict = new Dictionary(); + IDictionary> rvtLinkNamesToInstancesDict = + new Dictionary>(); + + try + { + View filterView = document.GetElement(originalFilterViewId) as View; + foreach (RevitLinkInstance rvtLinkInstance in idToTransform.Keys) + { + if (!IsLinkVisible(rvtLinkInstance, filterView)) + continue; + + // get the link document + Document linkDocument = rvtLinkInstance.GetLinkDocument(); + if (linkDocument == null) + continue; + + // get the link file path and name + String linkPathName = ""; + Parameter originalFileNameParam = linkDocument.ProjectInformation.LookupParameter("Original IFC File Name"); + if (originalFileNameParam != null && originalFileNameParam.StorageType == StorageType.String) + linkPathName = originalFileNameParam.AsString(); + else + linkPathName = linkDocument.PathName; + + // get the link file name + string linkFileName = GetLinkFileName(linkDocument, linkPathName); + + // add to names count dictionary + if (!rvtLinkNamesDict.Keys.Contains(linkFileName)) + rvtLinkNamesDict.Add(linkFileName, 0); + rvtLinkNamesDict[linkFileName]++; + + // add to names instances dictionary + if (!rvtLinkNamesToInstancesDict.Keys.Contains(linkPathName)) + rvtLinkNamesToInstancesDict.Add(linkPathName, new List()); + rvtLinkNamesToInstancesDict[linkPathName].Add(rvtLinkInstance); + } + } + catch + { + } + + foreach (KeyValuePair> linkPathNames in rvtLinkNamesToInstancesDict) + { + string linkPathName = linkPathNames.Key; + + // get the link instances + List currRvtLinkInstances = rvtLinkNamesToInstancesDict[linkPathName]; + IList linkFileNames = new List(); + IList> serTransforms = new List>(); + + Document linkDocument = null; + + foreach (RevitLinkInstance currRvtLinkInstance in currRvtLinkInstances) + { + // Nothing to report if the element itself is null. + if (currRvtLinkInstance == null) + continue; + + ElementId instanceId = currRvtLinkInstance.Id; + + // get the link document and the unit scale + linkDocument = linkDocument ?? currRvtLinkInstance.GetLinkDocument(); + + // get the link file path and name + string linkFileName = GetLinkFileName(linkDocument, linkPathName); + + //if link was an IFC file then make a different formating to the file name + if ((linkPathName.Length >= 4 && linkPathName.Substring(linkPathName.Length - 4).ToLower() == ".ifc") || + (linkPathName.Length >= 7 && linkPathName.Substring(linkPathName.Length - 7).ToLower() == ".ifcxml") || + (linkPathName.Length >= 7 && linkPathName.Substring(linkPathName.Length - 7).ToLower() == ".ifczip")) + { + string fName = fileName; + + //get output path and add to the new file name + index = fName.LastIndexOf("\\"); + if (index > 0) + fName = fName.Substring(0, index + 1); + else + fName = ""; + + //construct IFC file name + linkFileName = fName + linkFileName + "-"; + + //add guid + linkFileName += linkGUIDsCache[instanceId]; + } + else + { + // check if there are multiple instances with the same name + bool bMultiple = (rvtLinkNamesDict[linkFileName] > 1); + + // add the path + linkFileName = fileName + "-" + linkFileName; + + // add the guid + if (bMultiple) + { + linkFileName += "-"; + linkFileName += linkGUIDsCache[instanceId]; + } + } + + // add the extension + linkFileName += sExtension; + + linkFileNames.Add(linkFileName); + + // serialize transform + serTransforms.Add(Tuple.Create(instanceId, SerializeTransform(idToTransform[currRvtLinkInstance]))); + } + + if (linkDocument != null) + { + // export + try + { + int numLinkInstancesToExport = linkFileNames.Count; + exportOptions.AddOption("NumberOfExportedLinkInstances", numLinkInstancesToExport.ToString()); + + for (int ind = 0; ind < numLinkInstancesToExport; ind++) + { + string optionName = (ind == 0) ? "ExportLinkId" : "ExportLinkId" + (ind + 1).ToString(); + exportOptions.AddOption(optionName, serTransforms[ind].Item1.ToString()); + + optionName = (ind == 0) ? "ExportLinkInstanceTransform" : "ExportLinkInstanceTransform" + (ind + 1).ToString(); + exportOptions.AddOption(optionName, serTransforms[ind].Item2); + + // Don't pass in file name for the first link instance. + if (ind == 0) + continue; + + optionName = "ExportLinkInstanceFileName" + (ind + 1).ToString(); + exportOptions.AddOption(optionName, linkFileNames[ind]); + } + + // Pass in the first value; the rest will be in the options. + string path_ = Path.GetDirectoryName(linkFileNames[0]); + string fileName_ = Path.GetFileName(linkFileNames[0]); + + // Normally, IFC export would need a transaction, even if no permanent changes are made. For linked documents, though, that's + // handled by the export itself. + using (IFCLinkDocumentExportScope scope = new IFCLinkDocumentExportScope(linkDocument)) + { + linkDocument.Export(path_, fileName_, exportOptions); + } + } + catch + { + } + } + } + } + + /// + /// The FileNameListToString + /// + /// The fileNames + /// The + private string FileNameListToString(IList fileNames) + { + string fileNameListString = ""; + foreach (string fileName in fileNames) + { + if (fileNameListString != "") + fileNameListString += "; "; + fileNameListString += fileNames; + } + return fileNameListString; + } + + /// + /// The GetLinkedInstanceInfo + /// + /// The linkInstances + /// The + private (IDictionary, string, int) GetLinkedInstanceInfo( + IList linkInstances) + { + IDictionary linkedInstanceTransforms = + new SortedDictionary(new ElementComparer()); + + // We will keep track of the instances we can't export. Reasons we can't export: + // 1. Couldn't create a temporary document for exporting the linked instance. + // 2. The document for the linked instance can't be found. + // 3. The linked instance is mirrored, non-conformal, or scaled. + IList noTempDoc = new List(); + + IList nonConformalInst = new List(); + IList scaledInst = new List(); + IList instHasReflection = new List(); + + foreach (RevitLinkInstance currRvtLinkInstance in linkInstances) + { + // Nothing to report if the element itself is null. + if (currRvtLinkInstance == null) + continue; + + // get the link document and the unit scale + Document linkDocument = currRvtLinkInstance.GetLinkDocument(); + if (linkDocument == null) + { + // We can't distinguish between unloaded and an error condition, so we won't get a likely extraneous error. + continue; + } + + double lengthScaleFactorLink = UnitUtils.ConvertFromInternalUnits( + 1.0, + linkDocument.GetUnits().GetFormatOptions(SpecTypeId.Length).GetUnitTypeId()); + + // get the link transform + Transform tr = currRvtLinkInstance.GetTransform(); + + // We can't handle non-conformal, scaled, or mirrored transforms. + ElementId instanceId = currRvtLinkInstance.Id; + if (!tr.IsConformal) + { + nonConformalInst.Add(instanceId); + numBadInstances++; + continue; + } + + if (tr.HasReflection) + { + instHasReflection.Add(instanceId); + numBadInstances++; + continue; + } + + if (!MathUtil.IsAlmostEqual(tr.Determinant, 1.0)) + { + scaledInst.Add(instanceId); + numBadInstances++; + continue; + } + + // scale the transform origin + tr.Origin *= lengthScaleFactorLink; + + linkedInstanceTransforms[currRvtLinkInstance] = tr; + } + + // Show user errors, if any. + string expandedContent = string.Empty; + AddExpandedStringContent(ref expandedContent, Properties.Resources.LinkInstanceExportCantCreateDoc, noTempDoc); + AddExpandedElementIdContent(ref expandedContent, Properties.Resources.LinkInstanceExportNonConformal, nonConformalInst); + AddExpandedElementIdContent(ref expandedContent, Properties.Resources.LinkInstanceExportScaled, scaledInst); + AddExpandedElementIdContent(ref expandedContent, Properties.Resources.LinkInstanceExportHasReflection, instHasReflection); + + return (linkedInstanceTransforms, expandedContent, numBadInstances); + } + + /// + /// The GetLinkFileName + /// + /// The linkDocument + /// The linkPathName + /// The + private string GetLinkFileName(Document linkDocument, string linkPathName) + { + int index = linkPathName.LastIndexOf("\\"); + if (index <= 0) + return linkDocument.Title; + + string linkFileName = linkPathName.Substring(index + 1); + // remove the extension + index = linkFileName.LastIndexOf('.'); + if (index > 0) + linkFileName = linkFileName.Substring(0, index); + return linkFileName; + } + + /// + /// Checks if element is visible for certain view + /// + /// The element + /// The filterView + /// The + private bool IsLinkVisible(Element element, View filterView) + { + if (filterView == null) + return true; + + if (element.IsHidden(filterView)) + return false; + + if (!(element.Category?.get_Visible(filterView) ?? false)) + return false; + + return filterView.IsElementVisibleInTemporaryViewMode(TemporaryViewMode.TemporaryHideIsolate, element.Id); + } + + #endregion Private Methods + + #region Public Methods + + /// + /// The ExportSeparateDocuments + /// + /// The fullName + public void ExportSeparateDocuments(string fullName) + { + // We can't use the FilterViewId for linked documents, because the intermediate code assumes that it is in the exported document. As such, we + // will pass it in a special place. + ElementId originalFilterViewId = ifcOptions.FilterViewId; + if (originalFilterViewId != ElementId.InvalidElementId) + { + ifcOptions.AddOption("HostViewId", ifcOptions.FilterViewId.ToString()); + ifcOptions.FilterViewId = ElementId.InvalidElementId; + } + ExportOptionsCache.HostDocument = document; + ifcOptions.AddOption("ExportingLinks", LinkedFileExportAs.ExportAsSeparate.ToString()); + + ExportLinkedDocuments(document, fullName, linkGUIDsCache, linkInstanceTranforms, ifcOptions, originalFilterViewId); + } + + /// + /// The GetErrors + /// + /// The + public string GetErrors() + { + return errorMessage; + } + + /// + /// The GetNumberOfBadInstances + /// + /// The + public int GetNumberOfBadInstances() + { + return numBadInstances; + } + + /// + /// The ExportLinkedDocuments + /// + /// The linkExportKind + public void SetExportOption(LinkedFileExportAs linkExportKind) + { + int numBadInstances = 0; + + // Cache for links guids + FilteredElementCollector collector = new FilteredElementCollector(document); + ElementFilter elementFilter = new ElementClassFilter(typeof(RevitLinkInstance)); + List rvtLinkInstances = + collector.WherePasses(elementFilter).Cast().ToList(); + + string linkGuidOptionString = string.Empty; + + // Get the transforms of the links we can export, and error message information, including number, for the ones we can't. + (linkInstanceTranforms, errorMessage, numBadInstances) = + GetLinkedInstanceInfo(rvtLinkInstances); + + ISet existingGUIDs = new HashSet(); + bool inSeprateLinks = linkExportKind == LinkedFileExportAs.ExportAsSeparate; + + foreach (RevitLinkInstance linkInstance in linkInstanceTranforms.Keys) + { + Parameter parameter = linkInstance.get_Parameter(BuiltInParameter.IFC_GUID); + + string sGUID = GUIDUtil.GetSimpleElementIFCGUID(linkInstance); + + string sGUIDlower = sGUID.ToLower(); + + while (existingGUIDs.Contains(sGUIDlower)) + { + sGUID += "-"; + sGUIDlower += "-"; + } + existingGUIDs.Add(sGUIDlower); + + if (!inSeprateLinks) + linkGuidOptionString += linkInstance.Id.ToString() + "," + sGUID + ";"; + else + linkGUIDsCache.Add(linkInstance.Id, sGUID); + } + + if (!inSeprateLinks) + { + ifcOptions.AddOption("ExportingLinks", linkExportKind.ToString()); + ifcOptions.AddOption("FederatedLinkInfo", linkGuidOptionString); + } + } + + #endregion Public Methods + } +} From 7194e344c1e109924252ceaa30a3492224ef028a Mon Sep 17 00:00:00 2001 From: mostafa901 Date: Sat, 15 Jun 2024 17:05:31 +0200 Subject: [PATCH 3/4] Simplified usage so that no need to change the how user were using the tool --- Source/IFCExporterUIOverride/IFCExportConfiguration.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Source/IFCExporterUIOverride/IFCExportConfiguration.cs b/Source/IFCExporterUIOverride/IFCExportConfiguration.cs index fb329770..7eeeafcd 100644 --- a/Source/IFCExporterUIOverride/IFCExportConfiguration.cs +++ b/Source/IFCExporterUIOverride/IFCExportConfiguration.cs @@ -656,8 +656,6 @@ public void UpdateBuiltInConfiguration(IFCExportConfiguration updatedConfig) public void UpdateOptions(IFCExportOptions options, ElementId filterViewId) { options.FilterViewId = VisibleElementsOfCurrentView ? filterViewId : ElementId.InvalidElementId; - var linkExporter = ExportLinkedFiles == LinkedFileExportAs.DontExport ? null : new IFCLinkedDocumentExporter(IFCCommandOverrideApplication.TheDocument, options); - linkExporter?.SetExportOption(ExportLinkedFiles); foreach (var prop in GetType().GetProperties()) { switch (prop.Name) @@ -693,6 +691,13 @@ public void UpdateOptions(IFCExportOptions options, ElementId filterViewId) string classificationJsonStr = JsonConvert.SerializeObject(ClassificationSettings, dateFormatSettings); options.AddOption(prop.Name, classificationJsonStr); break; + case nameof(ExportLinkedFiles): + if (ExportLinkedFiles != LinkedFileExportAs.DontExport) + { + LinkExporter = new IFCLinkedDocumentExporter(IFCCommandOverrideApplication.TheDocument, options); + LinkExporter.SetExportOption(ExportLinkedFiles); + } + break; default: var propVal = prop.GetValue(this, null); if (propVal != null) @@ -702,7 +707,6 @@ public void UpdateOptions(IFCExportOptions options, ElementId filterViewId) } } - /// /// Identifies the version selected by the user. /// From a39c7e46804843384865b15c88fe1151f0edddeb Mon Sep 17 00:00:00 2001 From: mostafa901 Date: Sat, 15 Jun 2024 17:13:16 +0200 Subject: [PATCH 4/4] Exclude LinkExporter from Json also, easened the implementation --- .../IFCExporterUIOverride/IFCExportConfiguration.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Source/IFCExporterUIOverride/IFCExportConfiguration.cs b/Source/IFCExporterUIOverride/IFCExportConfiguration.cs index 7eeeafcd..2e050dbf 100644 --- a/Source/IFCExporterUIOverride/IFCExportConfiguration.cs +++ b/Source/IFCExporterUIOverride/IFCExportConfiguration.cs @@ -434,6 +434,13 @@ public Enum FacilityPredefinedType [JsonIgnore] public bool IsInSession { get; private set; } = false; + /// + /// Available after Calling public void UpdateOptions(IFCExportOptions options, ElementId filterViewId) + /// and LinkedFileExportAs should not be DontExport + /// + [JsonIgnore] + public IFCLinkedDocumentExporter LinkExporter { get; private set; } + /// /// Creates a new default configuration. /// @@ -642,11 +649,6 @@ public void UpdateBuiltInConfiguration(IFCExportConfiguration updatedConfig) } } - /// - /// Available after Calling public void UpdateOptions(IFCExportOptions options, ElementId filterViewId) - /// and LinkedFileExportAs should not be DontExport - /// - public IFCLinkedDocumentExporter LinkExporter { get; private set; } /// /// Updates the IFCExportOptions with the settings in this configuration.

57h+ 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%0A@EhYdMK?n? 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

9iKn& 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 z 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