| 992 | } |
| 993 | |
| 994 | boost::optional<SurfaceIntersection> Surface_Impl::computeIntersection(Surface& otherSurface) { |
| 995 | double tol = 0.01; // 1 cm tolerance |
| 996 | double areaTol = 0.001; // 10 cm2 tolerance |
| 997 | |
| 998 | constexpr bool extraLogging = false; |
| 999 | |
| 1000 | boost::optional<Space> space = this->space(); |
| 1001 | boost::optional<Space> otherSpace = otherSurface.space(); |
| 1002 | |
| 1003 | if (!space || !otherSpace || space->handle() == otherSpace->handle()) { |
| 1004 | LOG(Error, "Cannot find spaces for each surface in intersection or surfaces in same space."); |
| 1005 | return boost::none; |
| 1006 | } |
| 1007 | |
| 1008 | if (!this->subSurfaces().empty() || !otherSurface.subSurfaces().empty()) { |
| 1009 | LOG(Error, "Subsurfaces are not allowed in intersection"); |
| 1010 | return boost::none; |
| 1011 | } |
| 1012 | |
| 1013 | if (this->adjacentSurface() || otherSurface.adjacentSurface()) { |
| 1014 | LOG(Error, "Adjacent surfaces are not allowed in intersection"); |
| 1015 | return boost::none; |
| 1016 | } |
| 1017 | |
| 1018 | // goes from local system to building coordinates |
| 1019 | Transformation spaceTransformation = space->transformation(); |
| 1020 | Transformation otherSpaceTransformation = otherSpace->transformation(); |
| 1021 | |
| 1022 | // do the intersection in building coordinates |
| 1023 | |
| 1024 | Plane plane = spaceTransformation * this->plane(); |
| 1025 | Plane otherPlane = otherSpaceTransformation * otherSurface.plane(); |
| 1026 | |
| 1027 | if (!plane.reverseEqual(otherPlane)) { |
| 1028 | //LOG(Info, "Planes are not reverse equal, intersection of '" << this->name().get() << "' with '" << otherSurface.name().get() << "' fails"); |
| 1029 | return boost::none; |
| 1030 | } |
| 1031 | |
| 1032 | // get vertices in building coordinates |
| 1033 | std::vector<Point3d> buildingVertices = spaceTransformation * this->vertices(); |
| 1034 | std::vector<Point3d> otherBuildingVertices = otherSpaceTransformation * otherSurface.vertices(); |
| 1035 | |
| 1036 | if ((buildingVertices.size() < 3) || (otherBuildingVertices.size() < 3)) { |
| 1037 | LOG(Error, "Fewer than 3 vertices, intersection of '" << this->name().get() << "' with '" << otherSurface.name().get() << "' fails"); |
| 1038 | return boost::none; |
| 1039 | } |
| 1040 | |
| 1041 | // goes from face coordinates of building vertices to building coordinates |
| 1042 | Transformation faceTransformation; |
| 1043 | Transformation faceTransformationInverse; |
| 1044 | try { |
| 1045 | faceTransformation = Transformation::alignFace(buildingVertices); |
| 1046 | faceTransformationInverse = faceTransformation.inverse(); |
| 1047 | } catch (const std::exception&) { |
| 1048 | LOG(Error, "Cannot compute face transform, intersection of '" << this->name().get() << "' with '" << otherSurface.name().get() << "' fails"); |
| 1049 | return boost::none; |
| 1050 | } |
| 1051 | |