Creates one or more window subsurfaces along an edge
| 588 | |
| 589 | // Creates one or more window subsurfaces along an edge |
| 590 | void FloorspaceReverseTranslator_Impl::createWindowSubsurface(const FSWindow& window, Surface& osSurface, const FSEdge& edge, double minZ, |
| 591 | double maxZ) { |
| 592 | |
| 593 | auto windowDefinition = window.windowDefinition(); |
| 594 | if (!windowDefinition.has_value()) { |
| 595 | return; |
| 596 | } |
| 597 | |
| 598 | const auto& vertex1 = edge.firstVertex(); |
| 599 | const auto& vertex2 = edge.secondVertex(); |
| 600 | Vector3d edgeVector = edge.edgeVector(); |
| 601 | |
| 602 | edgeVector.setLength(1.0); |
| 603 | Vector3d upVector(0, 0, 1); |
| 604 | Vector3d crossVector = upVector.cross(edgeVector); |
| 605 | |
| 606 | double sillHeight = windowDefinition->sillHeight(); |
| 607 | double height = 0.0; |
| 608 | double width = 0.0; |
| 609 | if ((windowDefinition->windowDefinitionMode() == "Single Window") || (windowDefinition->windowDefinitionMode() == "Repeating Windows")) { |
| 610 | height = windowDefinition->height(); |
| 611 | width = windowDefinition->width(); |
| 612 | } else if (windowDefinition->windowDefinitionMode() == "Window to Wall Ratio") { |
| 613 | double length = edge.edgeVector().length(); |
| 614 | width = length - 0.0508; // Allow for 1" either end of the window |
| 615 | // Area of the wall * wwr gives area of the window divided by width of the window gives height of the window |
| 616 | height = (maxZ - minZ) * length * windowDefinition->wwr() / width; |
| 617 | } |
| 618 | |
| 619 | for (double alpha : window.alphas()) { |
| 620 | // Calculate the window center from the alpha and sill height |
| 621 | double x = (1.0 - alpha) * vertex1.x() + alpha * vertex2.x(); |
| 622 | double y = (1.0 - alpha) * vertex1.y() + alpha * vertex2.y(); |
| 623 | Point3d windowCenter(x, y, 0); |
| 624 | edgeVector.setLength(0.5 * width); |
| 625 | Point3d window1 = windowCenter + edgeVector; |
| 626 | edgeVector.setLength(-0.5 * width); |
| 627 | Point3d window2 = windowCenter + edgeVector; |
| 628 | |
| 629 | Point3dVector windowVertices; |
| 630 | windowVertices.push_back(Point3d(window1.x(), window1.y(), minZ + sillHeight + height)); |
| 631 | windowVertices.push_back(Point3d(window1.x(), window1.y(), minZ + sillHeight)); |
| 632 | windowVertices.push_back(Point3d(window2.x(), window2.y(), minZ + sillHeight)); |
| 633 | windowVertices.push_back(Point3d(window2.x(), window2.y(), minZ + sillHeight + height)); |
| 634 | |
| 635 | // Make sure the sub-surface orientation matches the surface |
| 636 | Plane plane1(osSurface.vertices()); |
| 637 | Plane plane2(windowVertices); |
| 638 | if (plane1.reverseEqual(plane2)) { |
| 639 | std::reverse(windowVertices.begin(), windowVertices.end()); |
| 640 | Point3d temp = window1; |
| 641 | window1 = window2; |
| 642 | window2 = temp; |
| 643 | edgeVector = edgeVector.reverseVector(); |
| 644 | crossVector = crossVector.reverseVector(); |
| 645 | } |
| 646 | |
| 647 | SubSurface subSurface(windowVertices, m_model); |
nothing calls this directly
no test coverage detected