From a7bbb35c5e596de6e442c9d33eb35ecfd0a82b13 Mon Sep 17 00:00:00 2001 From: D4ve-R Date: Sun, 7 May 2023 11:45:47 +0200 Subject: [PATCH] compile & link successful --- cmake/CMakeLists.txt | 70 +++++++++++++++++++++++++++---- src/ifcconvert/IfcConvert.cpp | 5 ++- src/serializers/USDSerializer.cpp | 57 +++++++++++-------------- src/serializers/USDSerializer.h | 19 ++++++++- 4 files changed, 108 insertions(+), 43 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 2dc3730e32..80efd3d98b 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -54,12 +54,14 @@ OPTION(USE_VLD "Use Visual Leak Detector for debugging memory leaks, MSVC-only." OPTION(USE_MMAP "Adds a command line options to parse IFC files from memory mapped files using Boost.Iostreams" OFF) OPTION(BUILD_SHARED_LIBS "Build IfcParse and IfcGeom as shared libs (SO/DLL)." OFF) OPTION(MSVC_PARALLEL_BUILD "Multi-threaded compilation in Microsoft Visual Studio (/MP)" OFF) +OPTION(NO_WARN "Disable all warnings" OFF) OPTION(WASM_BUILD OFF) if (${HAS_MAX}) OPTION(BUILD_IFCMAX "Build IfcMax, a 3ds Max plug-in, Windows-only." OFF) endif() if (${BUILD_CONVERT}) OPTION(GLTF_SUPPORT "Build IfcConvert with glTF support (requires json.hpp)." OFF) +OPTION(USD_SUPPORT "Build IfcConvert with USD support (requires pixar's USD library)." OFF) endif() OPTION(USERSPACE_PYTHON_PREFIX "Installs IfcPython for the current user only instead of system-wide." OFF) OPTION(ADD_COMMIT_SHA "Add commit sha and branch in version number, warning results in many rebuilds, requires git" OFF) @@ -72,6 +74,14 @@ if(MSVC AND MSVC_PARALLEL_BUILD) add_definitions("/MP") endif() +if(NO_WARN) + if(MSVC) + add_compile_options("/w") + else() + add_compile_options("-w") + endif() +endif() + # QtViewer requires Qt5 OPTION(BUILD_QTVIEWER "Build IfcOpenShell Qt GUI Viewer" OFF) include(GNUInstallDirs) @@ -137,11 +147,6 @@ UNIFY_ENVVARS_AND_CACHE(PYTHON_EXECUTABLE) UNIFY_ENVVARS_AND_CACHE(HDF5_INCLUDE_DIR) UNIFY_ENVVARS_AND_CACHE(HDF5_LIBRARY_DIR) UNIFY_ENVVARS_AND_CACHE(HDF5_LIBRARIES) -endif() -UNIFY_ENVVARS_AND_CACHE(BOOST_ROOT) -UNIFY_ENVVARS_AND_CACHE(BOOST_LIBRARYDIR) - -if (NOT MINIMAL_BUILD) UNIFY_ENVVARS_AND_CACHE(CGAL_INCLUDE_DIR) UNIFY_ENVVARS_AND_CACHE(CGAL_LIBRARY_DIR) UNIFY_ENVVARS_AND_CACHE(GMP_INCLUDE_DIR) @@ -149,6 +154,8 @@ UNIFY_ENVVARS_AND_CACHE(GMP_LIBRARY_DIR) UNIFY_ENVVARS_AND_CACHE(MPFR_INCLUDE_DIR) UNIFY_ENVVARS_AND_CACHE(MPFR_LIBRARY_DIR) endif() +UNIFY_ENVVARS_AND_CACHE(BOOST_ROOT) +UNIFY_ENVVARS_AND_CACHE(BOOST_LIBRARYDIR) if(WASM_BUILD) # when using the nix/build-all.py build script we should not @@ -170,6 +177,54 @@ add_definitions(-DWITH_GLTF) set(SWIG_DEFINES ${SWIG_DEFINES} -DWITH_GLTF) endif() +# Add USD support to serializers +if(NOT MINIMAL_BUILD AND USD_SUPPORT) + UNIFY_ENVVARS_AND_CACHE(USD_INCLUDE_DIR) + UNIFY_ENVVARS_AND_CACHE(USD_LIBRARY_DIR) + + if("${USD_INCLUDE_DIR}" STREQUAL "") + find_path(USD_INCLUDE_DIR pxr.h + [PATHS + /usr/include/pxr + /usr/local/include/pxr + ] + REQUIRED + ) + if(USD_INCLUDE_DIR) + message(STATUS "Found USD include files in: ${USD_INCLUDE_DIR}") + else() + message(FATAL_ERROR "Unable to find USD include directory, specify USD_INCLUDE_DIR manually.") + endif() + else() + set(USD_INCLUDE_DIR ${USD_INCLUDE_DIR} CACHE FILEPATH "USD header files") + message(STATUS "Looking for USD include files in: ${USD_INCLUDE_DIR}") + endif() + + set(USD_LIBRARIES + usd_usd + usd_usdGeom + usd_usdShade + usd_usdLux + usd_vt + usd_sdf + usd_tf + usd_gf + ) + + find_library(USD_LIBRARY + NAMES ${USD_LIBRARIES} + PATHS ${USD_LIBRARY_DIR}) + if(USD_LIBRARY) + message(STATUS "USD libraries ${USD_LIBRARIES} found in: ${USD_LIBRARY_DIR}") + link_directories(${USD_LIBRARY_DIR}) + else() + message(FATAL_ERROR "Unable to find USD libraries in: ${USD_LIBRARY_DIR}") + endif() + + add_definitions(-DWITH_USD) + set(SWIG_DEFINES ${SWIG_DEFINES} -DWITH_USD) +endif() + # Set INSTALL_RPATH for target MACRO(SET_INSTALL_RPATHS _target _paths) SET(${_target}_rpaths "") @@ -633,6 +688,7 @@ ENDIF() INCLUDE_DIRECTORIES(${INCLUDE_DIRECTORIES} ${OCC_INCLUDE_DIR} ${OPENCOLLADA_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} ${LIBXML2_INCLUDE_DIR} ${JSON_INCLUDE_DIR} ${HDF5_INCLUDE_DIR} + ${USD_INCLUDE_DIR} ) function(files_for_ifc_version IFC_VERSION RESULT_NAME) @@ -841,7 +897,7 @@ endforeach() add_library(Serializers ${SERIALIZERS_FILES}) set_target_properties(Serializers PROPERTIES COMPILE_FLAGS "-DIFC_GEOM_EXPORTS ${CONVERT_PRECISION}" VERSION "0.6.0" SOVERSION "0.6") -TARGET_LINK_LIBRARIES(Serializers ${SERIALIZER_SCHEMA_LIBRARIES} ${OPENCOLLADA_LIBRARIES}) +TARGET_LINK_LIBRARIES(Serializers ${SERIALIZER_SCHEMA_LIBRARIES} ${OPENCOLLADA_LIBRARIES} ${USD_LIBRARIES}) endif(BUILD_CONVERT or BUILD_IFCPYTHON) @@ -854,7 +910,7 @@ set(IFCCONVERT_FILES ${IFCCONVERT_CPP_FILES} ${IFCCONVERT_H_FILES}) ADD_EXECUTABLE(IfcConvert ${IFCCONVERT_FILES}) set_target_properties(IfcConvert PROPERTIES COMPILE_FLAGS "${CONVERT_PRECISION}") -TARGET_LINK_LIBRARIES(IfcConvert ${IFCOPENSHELL_LIBRARIES} ${OPENCASCADE_LIBRARIES} ${Boost_LIBRARIES} ${HDF5_LIBRARIES}) +TARGET_LINK_LIBRARIES(IfcConvert ${IFCOPENSHELL_LIBRARIES} ${OPENCASCADE_LIBRARIES} ${Boost_LIBRARIES} ${HDF5_LIBRARIES} ${USD_LIBRARIES}) if ((NOT WIN32) AND BUILD_SHARED_LIBS) # Only set RPATHs when building shared libraries (i.e. IfcParse and diff --git a/src/ifcconvert/IfcConvert.cpp b/src/ifcconvert/IfcConvert.cpp index ba427dbd0a..fdc73f5807 100644 --- a/src/ifcconvert/IfcConvert.cpp +++ b/src/ifcconvert/IfcConvert.cpp @@ -711,7 +711,8 @@ int main(int argc, char** argv) { CACHE = IfcUtil::path::from_utf8(".cache"), HDF = IfcUtil::path::from_utf8(".h5"), XML = IfcUtil::path::from_utf8(".xml"), - IFC = IfcUtil::path::from_utf8(".ifc"); + IFC = IfcUtil::path::from_utf8(".ifc"), + USD = IfcUtil::path::from_utf8(".usd"); // @todo clean up serializer selection // @todo detect program options that conflict with the chosen serializer @@ -857,7 +858,7 @@ int main(int argc, char** argv) { #endif #ifdef WITH_USD } else if (output_extension == USD) { - serializer = boost::make_shared(IfcUtil::path::to_utf8(output_temp_filename), settings); + serializer = boost::make_shared(IfcUtil::path::to_utf8(output_temp_filename), settings); #endif } else if (output_extension == STP) { serializer = boost::make_shared(IfcUtil::path::to_utf8(output_temp_filename), settings); diff --git a/src/serializers/USDSerializer.cpp b/src/serializers/USDSerializer.cpp index 95d5c161fc..18667566a2 100644 --- a/src/serializers/USDSerializer.cpp +++ b/src/serializers/USDSerializer.cpp @@ -2,15 +2,11 @@ #include "USDSerializer.h" -#include "../ifcparse/utils.h" - -#include "pxr/usd/sdf/path.h" -#include "pxr/usd/gf/vec3f.h" -#include "pxr/usd/gf/rotation.h" -#include "pxr/usd/tf/token.h" +#include "pxr/base/tf/token.h" +#include "pxr/base/gf/vec3f.h" +#include "pxr/base/gf/rotation.h" #include "pxr/usd/usdGeom/xform.h" #include "pxr/usd/usdGeom/xformOp.h" -#include "pxr/usd/usdGeom/mesh.h" #include "pxr/usd/usdGeom/tokens.h" #include "pxr/usd/usdGeom/scope.h" #include "pxr/usd/usdLux/distantLight.h" @@ -20,23 +16,16 @@ #include "pxr/usd/usdShade/materialBindingAPI.h" #include "pxr/usd/usdShade/connectableAPI.h" - -#include #include #include - USDSerializer::USDSerializer(const std::string& filename, const SerializerSettings& settings) : WriteOnlyGeometrySerializer(settings) , filename_(filename) - , settings_(settings) { // create a new stage stage_ = pxr::UsdStage::CreateNew(filename + ".usda"); - if( !settings().get(SerializerSettings::USE_Y_UP) ) - stage_->SetDefaultPrim(pxr::UsdGeomXform::Define(stage_, pxr::SdfPath("/"), pxr::UsdGeomTokens->z)); - else - stage_->SetDefaultPrim(pxr::UsdGeomXform::Define(stage_, pxr::SdfPath("/"), pxr::UsdGeomTokens->y)); + // create root xform prim 'World' pxr::UsdGeomXform::Define(stage_, pxr::SdfPath("/World")); pxr::UsdGeomScope::Define(stage_, pxr::SdfPath("/Looks")); @@ -55,7 +44,7 @@ void USDSerializer::createLighting() { // set the light's orientation pxr::UsdGeomXform xform(stage_->GetPrimAtPath(pxr::SdfPath(light_path))); pxr::GfVec3f light_direction(0.0f, 0.0f, -1.0f); - xform.AddRotateOp(pxr::UsdGeomXformOp::PrecisionFloat, pxr::UsdGeomXformOp::TypeRotateXYZ).Set(pxr::GfRotation(pxr::GfVec3f(0.0f, 1.0f, 0.0f), light_direction).GetQuaternion()); + //xform.AddRotateOp(pxr::UsdGeomXformOp::PrecisionFloat, pxr::UsdGeomXformOp::TypeRotateXYZ).Set(pxr::GfRotation(pxr::GfVec3f(0.0f, 1.0f, 0.0f), light_direction).GetQuaternion()); // set the light's color pxr::UsdLuxDistantLight light(stage_->GetPrimAtPath(pxr::SdfPath(light_path))); light.CreateIntensityAttr().Set(1000.0f); @@ -68,11 +57,11 @@ void USDSerializer::writeMaterial(const pxr::UsdGeomMesh& mesh,const IfcGeom::Ma pxr::UsdShadeMaterial::Define(stage_, pxr::SdfPath(ss.str())); pxr::UsdShadeMaterial material(stage_->GetPrimAtPath(pxr::SdfPath(ss.str()))); pxr::UsdShadeShader shader = pxr::UsdShadeShader::Define(stage_, pxr::SdfPath(ss.str() + "/Shader")); - shader.CreateIdAttr().Set(TfToken("UsdPreviewSurface")); + shader.CreateIdAttr().Set(pxr::TfToken("UsdPreviewSurface")); float rgba[4] { 0.18f, 0.18f, 0.18f, 1.0f }; if (style.hasDiffuse()) - for (int i = 0; i < 3; ++i) rgba[i] = static_cast style.diffuse()[i]; + for (int i = 0; i < 3; ++i) rgba[i] = static_cast(style.diffuse()[i]); shader.CreateInput(pxr::TfToken("diffuseColor"), pxr::SdfValueTypeNames->Color3f).Set(pxr::GfVec3f(rgba[0], rgba[1], rgba[2])); if(style.hasTransparency()) @@ -80,15 +69,15 @@ void USDSerializer::writeMaterial(const pxr::UsdGeomMesh& mesh,const IfcGeom::Ma shader.CreateInput(pxr::TfToken("opacity"), pxr::SdfValueTypeNames->Float).Set(rgba[3]); if(style.hasSpecular()) { - for (int i = 0; i < 3; ++i) rgba[i] = static_cast style.specular()[i]; + for (int i = 0; i < 3; ++i) rgba[i] = static_cast(style.specular()[i]); shader.CreateInput(pxr::TfToken("useSpecularWorkflow"), pxr::SdfValueTypeNames->Int).Set(1); } else { shader.CreateInput(pxr::TfToken("useSpecularWorkflow"), pxr::SdfValueTypeNames->Int).Set(0); } shader.CreateInput(pxr::TfToken("specularColor"), pxr::SdfValueTypeNames->Color3f).Set(pxr::GfVec3f(rgba[0], rgba[1], rgba[2])); - material.CreateSurfaceOutput().ConnectToSource(shader, pxr::TfToken("surface")); - pxr::UsdShadeMaterialBindingAPI(mesh).Bind(material); + //material.CreateSurfaceOutput().ConnectToSource(shader, pxr::TfToken("surface")); + //pxr::UsdShadeMaterialBindingAPI(mesh).Bind(material); } bool USDSerializer::ready() { @@ -102,23 +91,25 @@ void USDSerializer::writeHeader() { } void USDSerializer::write(const IfcGeom::TriangulationElement* o) { - if ( o->geometry().material_ids().empty() ) + const IfcGeom::Representation::Triangulation& mesh = o->geometry(); + if ( mesh.material_ids().empty() || mesh.verts().empty() || mesh.faces().empty() ) return; - std:sstringstream ss("/World/"); - ss << o->geometry().id(); - pxr::UsdGeomMesh::Define(stage_, pxr::SdfPath(ss.str())); - const IfcGeom::Representation::Triangulation& mesh = o->geometry(); + std::stringstream ss("/World/"); + ss << mesh.id(); + pxr::UsdGeomMesh usd_mesh = pxr::UsdGeomMesh::Define(stage_, pxr::SdfPath(ss.str())); const std::vector& m = o->transformation().matrix().data(); - const int vcount = (int)mesh.verts().size() / 3; + const int vcount = (int) mesh.verts().size() / 3; + pxr::VtVec3dArray points; for ( std::vector::const_iterator it = mesh.verts().begin(); it != mesh.verts().end(); ) { - const double x = *(it++); - const double y = *(it++); - const double z = *(it++); - - - } + points.push_back(pxr::GfVec3d(*(it++), *(it++), *(it++))); + } + usd_mesh.CreatePointsAttr().Set(points); + usd_mesh.CreateFaceVertexIndicesAttr().Set(usd_utils::toVtArray(mesh.faces())); + const int fcount = (int) mesh.faces().size() / 3; + usd_mesh.CreateFaceVertexCountsAttr().Set(pxr::VtArray(fcount, 3)); + usd_mesh.CreateNormalsAttr().Set(usd_utils::toVtArray(mesh.normals())); } diff --git a/src/serializers/USDSerializer.h b/src/serializers/USDSerializer.h index aa50258802..39d9ef0aef 100644 --- a/src/serializers/USDSerializer.h +++ b/src/serializers/USDSerializer.h @@ -24,10 +24,27 @@ #include "../serializers/serializers_api.h" #include "../ifcgeom_schema_agnostic/GeometrySerializer.h" +#include "../ifcparse/utils.h" + +// undefine opencascade Handle macro, because it conflicts with USD +#undef Handle #include "pxr/pxr.h" #include "pxr/usd/usd/stage.h" +#include "pxr/base/vt/array.h" +#include "pxr/usd/usdGeom/mesh.h" +#include + +namespace usd_utils { + template + pxr::VtArray toVtArray(const std::vector& vec) { + auto array = pxr::VtArray(vec.size()); + for (size_t i = 0; i < vec.size(); ++i) + array[i] = vec[i]; + return array; + } +} class SERIALIZERS_API USDSerializer : public WriteOnlyGeometrySerializer { private: @@ -35,7 +52,7 @@ private: bool ready_ = false; pxr::UsdStageRefPtr stage_; - int writeMaterial(const IfcGeom::Material&); + void writeMaterial(const pxr::UsdGeomMesh&, const IfcGeom::Material&); void createLighting(); public: USDSerializer(const std::string&, const SerializerSettings&);