------------------------------------------------------------------------------------------------
| 132 | |
| 133 | // ------------------------------------------------------------------------------------------------ |
| 134 | void ProcessBooleanHalfSpaceDifference(const Schema_2x3::IfcHalfSpaceSolid *hs, TempMesh &result, |
| 135 | const TempMesh &first_operand, |
| 136 | ConversionData & /*conv*/) { |
| 137 | ai_assert(hs != nullptr); |
| 138 | |
| 139 | const Schema_2x3::IfcPlane *const plane = hs->BaseSurface->ToPtr<Schema_2x3::IfcPlane>(); |
| 140 | if (!plane) { |
| 141 | IFCImporter::LogError("expected IfcPlane as base surface for the IfcHalfSpaceSolid"); |
| 142 | return; |
| 143 | } |
| 144 | |
| 145 | // extract plane base position vector and normal vector |
| 146 | IfcVector3 p, n(0.f, 0.f, 1.f); |
| 147 | if (plane->Position->Axis) { |
| 148 | ConvertDirection(n, plane->Position->Axis.Get()); |
| 149 | } |
| 150 | ConvertCartesianPoint(p, plane->Position->Location); |
| 151 | |
| 152 | if (!IsTrue(hs->AgreementFlag)) { |
| 153 | n *= -1.f; |
| 154 | } |
| 155 | |
| 156 | // clip the current contents of `meshout` against the plane we obtained from the second operand |
| 157 | const std::vector<IfcVector3> &in = first_operand.mVerts; |
| 158 | std::vector<IfcVector3> &outvert = result.mVerts; |
| 159 | |
| 160 | std::vector<unsigned int>::const_iterator begin = first_operand.mVertcnt.begin(), |
| 161 | end = first_operand.mVertcnt.end(), iit; |
| 162 | |
| 163 | outvert.reserve(in.size()); |
| 164 | result.mVertcnt.reserve(first_operand.mVertcnt.size()); |
| 165 | |
| 166 | unsigned int vidx = 0; |
| 167 | for (iit = begin; iit != end; vidx += *iit++) { |
| 168 | |
| 169 | unsigned int newcount = 0; |
| 170 | bool isAtWhiteSide = (in[vidx] - p) * n > -ai_epsilon; |
| 171 | for (unsigned int i = 0; i < *iit; ++i) { |
| 172 | const IfcVector3 &e0 = in[vidx + i], e1 = in[vidx + (i + 1) % *iit]; |
| 173 | |
| 174 | // does the next segment intersect the plane? |
| 175 | IfcVector3 isectpos; |
| 176 | if (IntersectSegmentPlane(p, n, e0, e1, isAtWhiteSide, isectpos)) { |
| 177 | if (isAtWhiteSide) { |
| 178 | // e0 is on the right side, so keep it |
| 179 | outvert.push_back(e0); |
| 180 | outvert.push_back(isectpos); |
| 181 | newcount += 2; |
| 182 | } else { |
| 183 | // e0 is on the wrong side, so drop it and keep e1 instead |
| 184 | outvert.push_back(isectpos); |
| 185 | ++newcount; |
| 186 | } |
| 187 | isAtWhiteSide = !isAtWhiteSide; |
| 188 | } else { |
| 189 | if (isAtWhiteSide) { |
| 190 | outvert.push_back(e0); |
| 191 | ++newcount; |
no test coverage detected