Skip to content

Commit

Permalink
Merge pull request #3971 from NREL/3943_ThreeJS_ConstructionAirBoundary
Browse files Browse the repository at this point in the history
Fix #3943 - ThreeJS handle ConstructionAirBoundary as "AirWall" material
  • Loading branch information
tijcolem authored May 7, 2020
2 parents 91832e0 + de3a365 commit 8ae4d88
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 14 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Do not enable compiler specific extensions, for eg on GCC use -std=c++1z (=c++17) and not -std=gnu++17
set(CMAKE_CXX_EXTENSIONS OFF)

# Use ccache is available, has to be before "project()"
# Use ccache if available, has to be before "project()"
find_program(CCACHE_PROGRAM ccache)
if(CCACHE_PROGRAM)
# Support Unix Makefiles and Ninja
Expand Down
25 changes: 18 additions & 7 deletions src/model/ThreeJSForwardTranslator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
#include "RenderingColor.hpp"
#include "ConstructionBase.hpp"
#include "ConstructionBase_Impl.hpp"
#include "ConstructionAirBoundary.hpp"
#include "ConstructionAirBoundary_Impl.hpp"
#include "ThermalZone.hpp"
#include "ThermalZone_Impl.hpp"
#include "SpaceType.hpp"
Expand Down Expand Up @@ -85,15 +87,19 @@ namespace openstudio
{
// make construction materials
for (auto& construction : model.getModelObjects<ConstructionBase>()){
boost::optional<RenderingColor> color = construction.renderingColor();
if (!color){
color = RenderingColor(model);
construction.setRenderingColor(*color);
// If it's ConstructionAirBoundary, we'll later use the standard material "AirWall"
if (!construction.optionalCast<ConstructionAirBoundary>()) {
boost::optional<RenderingColor> color = construction.renderingColor();
if (!color){
color = RenderingColor(model);
construction.setRenderingColor(*color);
}
std::string name = getObjectThreeMaterialName(construction);
addThreeMaterial(materials, materialMap, makeThreeMaterial(name, toThreeColor(color->renderingRedValue(), color->renderingBlueValue(), color->renderingGreenValue()), 1, ThreeSide::DoubleSide));
}
std::string name = getObjectThreeMaterialName(construction);
addThreeMaterial(materials, materialMap, makeThreeMaterial(name, toThreeColor(color->renderingRedValue(), color->renderingBlueValue(), color->renderingGreenValue()), 1, ThreeSide::DoubleSide));
}


// make thermal zone materials
for (auto& thermalZone : model.getConcreteModelObjects<ThermalZone>()){
boost::optional<RenderingColor> color = thermalZone.renderingColor();
Expand Down Expand Up @@ -259,7 +265,12 @@ namespace openstudio
if (construction)
{
userData.setConstructionName(construction->nameString());
userData.setConstructionMaterialName(getObjectThreeMaterialName(*construction));
// If this is a ConstructionAirBoundary, then set to the standard material "AirWall"
if (construction->optionalCast<ConstructionAirBoundary>()) {
userData.setConstructionMaterialName("AirWall");
} else {
userData.setConstructionMaterialName(getObjectThreeMaterialName(*construction));
}
}

if (space)
Expand Down
73 changes: 73 additions & 0 deletions src/model/test/ThreeJSForwardTranslator_GTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,13 @@
#include "../Space_Impl.hpp"
#include "../Surface.hpp"
#include "../Surface_Impl.hpp"
#include "../ConstructionAirBoundary.hpp"
#include "../Construction.hpp"

#include "../../utilities/geometry/ThreeJS.hpp"

#include <algorithm>

using namespace openstudio;
using namespace openstudio::model;

Expand All @@ -55,6 +59,18 @@ TEST_F(ModelFixture,ThreeJSForwardTranslator_ExampleModel) {

// triangulated, for display
ThreeScene scene = ft.modelToThreeJS(model, true);
// Ensure we get no errors or warnings, generally speaking.
EXPECT_EQ(0, ft.errors().size());
EXPECT_EQ(0, ft.warnings().size());

for (const auto& error : ft.errors()){
EXPECT_TRUE(false) << "Error: " << error.logMessage();
}

for (const auto& warning : ft.warnings()){
EXPECT_TRUE(false) << "Warning: " << warning.logMessage();
}

std::string json = scene.toJSON();
EXPECT_TRUE(ThreeScene::load(json));

Expand All @@ -66,6 +82,19 @@ TEST_F(ModelFixture,ThreeJSForwardTranslator_ExampleModel) {

// not triangulated, for model transport/translation
scene = ft.modelToThreeJS(model, false);

// Ensure we get no errors or warnings, generally speaking.
EXPECT_EQ(0, ft.errors().size());
EXPECT_EQ(0, ft.warnings().size());

for (const auto& error : ft.errors()){
EXPECT_TRUE(false) << "Error: " << error.logMessage();
}

for (const auto& warning : ft.warnings()){
EXPECT_TRUE(false) << "Warning: " << warning.logMessage();
}

json = scene.toJSON();
EXPECT_TRUE(ThreeScene::load(json));

Expand All @@ -83,3 +112,47 @@ TEST_F(ModelFixture,ThreeJSForwardTranslator_ExampleModel) {
EXPECT_EQ(model.getConcreteModelObjects<Space>().size(), model2->getConcreteModelObjects<Space>().size());
EXPECT_EQ(model.getConcreteModelObjects<Surface>().size(), model2->getConcreteModelObjects<Surface>().size());
}

TEST_F(ModelFixture,ThreeJSForwardTranslator_ConstructionAirBoundary) {

ThreeJSForwardTranslator ft;

Model m;
ConstructionAirBoundary cAirBoundary(m);
cAirBoundary.setName("Construction_Air_Boundary");

Construction c(m);
c.setName("RegularConstruction");

ThreeScene scene = ft.modelToThreeJS(m, false);

// Ensure we get no errors or warnings, generally speaking.
// Here I'm especially after #3943: "Unknown iddObjectType 'OS:Construction:AirBoundary'"
EXPECT_EQ(0, ft.errors().size());
EXPECT_EQ(0, ft.warnings().size());

for (const auto& error : ft.errors()){
EXPECT_TRUE(false) << "Error: " << error.logMessage();
}

for (const auto& warning : ft.warnings()){
EXPECT_TRUE(false) << "Warning: " << warning.logMessage();
}


// Materials are named like "prefix_" + <construction.name>
auto checkIfMaterialExist = [](const auto& materials, const std::string& containedString) {
auto it = std::find_if(materials.cbegin(), materials.cend(),
[&containedString](const auto& mat){
return mat.name().find(containedString) != std::string::npos;
}
);
return it != materials.cend();
};

auto materials = scene.materials();
EXPECT_TRUE(checkIfMaterialExist(materials, "RegularConstruction"));
EXPECT_FALSE(checkIfMaterialExist(materials, "Construction_Air_Boundary")); // Instead it should have been skipped to be replace by "AirWall"
EXPECT_TRUE(checkIfMaterialExist(materials, "AirWall"));

}
16 changes: 10 additions & 6 deletions src/utilities/geometry/ThreeJS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,16 +77,20 @@ namespace openstudio{
std::string result;
if (istringEqual(iddObjectType, "OS:Construction")){
result = "Construction_" + name;
}else if (istringEqual(iddObjectType, "OS:ThermalZone")){
} else if (istringEqual(iddObjectType, "OS:ThermalZone")){
result = "ThermalZone_" + name;
}else if (istringEqual(iddObjectType, "OS:SpaceType")){
} else if (istringEqual(iddObjectType, "OS:SpaceType")){
result = "SpaceType_" + name;
}else if (istringEqual(iddObjectType, "OS:BuildingStory")){
} else if (istringEqual(iddObjectType, "OS:BuildingStory")){
result = "BuildingStory_" + name;
}else if (istringEqual(iddObjectType, "OS:BuildingUnit")){
} else if (istringEqual(iddObjectType, "OS:BuildingUnit")){
result = "BuildingUnit_" + name;
} else{
LOG_FREE(Error, "getObjectMaterialName", "Unknown iddObjectType '" << iddObjectType << "'");
} else if (istringEqual(iddObjectType, "OS:Construction:AirBoundary")){
// This shouldn't happen
LOG_FREE(Error, "getObjectThreeMaterialName", "Didn't expect it would be called for '" << iddObjectType << "' (name = '" << name << "')");
result = "ConstructionAirBoundary_" + name;
} else {
LOG_FREE(Error, "getObjectThreeMaterialName", "Unknown iddObjectType '" << iddObjectType << "'");
}
return result;
}
Expand Down

0 comments on commit 8ae4d88

Please sign in to comment.