------------------------------------------------------------------------------------------------
| 670 | |
| 671 | // ------------------------------------------------------------------------------------------------ |
| 672 | void ProcessBooleanExtrudedAreaSolidDifference(const Schema_2x3::IfcExtrudedAreaSolid *as, |
| 673 | TempMesh &result, |
| 674 | const TempMesh &first_operand, |
| 675 | ConversionData &conv) { |
| 676 | ai_assert(as != nullptr); |
| 677 | |
| 678 | // This case is handled by reduction to an instance of the quadrify() algorithm. |
| 679 | // Obviously, this won't work for arbitrarily complex cases. In fact, the first |
| 680 | // operand should be near-planar. Luckily, this is usually the case in Ifc |
| 681 | // buildings. |
| 682 | |
| 683 | std::shared_ptr<TempMesh> meshtmp = std::make_shared<TempMesh>(); |
| 684 | ProcessExtrudedAreaSolid(*as, *meshtmp, conv, false); |
| 685 | |
| 686 | std::vector<TempOpening> openings(1, TempOpening(as, IfcVector3(0, 0, 0), std::move(meshtmp), std::shared_ptr<TempMesh>())); |
| 687 | |
| 688 | result = first_operand; |
| 689 | |
| 690 | TempMesh temp; |
| 691 | |
| 692 | std::vector<IfcVector3>::const_iterator vit = first_operand.mVerts.begin(); |
| 693 | for (unsigned int pcount : first_operand.mVertcnt) { |
| 694 | temp.Clear(); |
| 695 | |
| 696 | temp.mVerts.insert(temp.mVerts.end(), vit, vit + pcount); |
| 697 | temp.mVertcnt.push_back(pcount); |
| 698 | |
| 699 | // The algorithms used to generate mesh geometry sometimes |
| 700 | // spit out lines or other degenerates which must be |
| 701 | // filtered to avoid running into assertions later on. |
| 702 | |
| 703 | // ComputePolygonNormal returns the Newell normal, so the |
| 704 | // length of the normal is the area of the polygon. |
| 705 | const IfcVector3 &normal = temp.ComputeLastPolygonNormal(false); |
| 706 | if (normal.SquareLength() < static_cast<IfcFloat>(1e-5)) { |
| 707 | IFCImporter::LogWarn("skipping degenerate polygon (ProcessBooleanExtrudedAreaSolidDifference)"); |
| 708 | continue; |
| 709 | } |
| 710 | |
| 711 | GenerateOpenings(openings, temp, false, true); |
| 712 | result.Append(temp); |
| 713 | |
| 714 | vit += pcount; |
| 715 | } |
| 716 | |
| 717 | IFCImporter::LogVerboseDebug("generating CSG geometry by geometric difference to a solid (IfcExtrudedAreaSolid)"); |
| 718 | } |
| 719 | |
| 720 | // ------------------------------------------------------------------------------------------------ |
| 721 | void ProcessBoolean(const Schema_2x3::IfcBooleanResult &boolean, TempMesh &result, ConversionData &conv) { |
no test coverage detected