| 178 | } // anonymous namespace |
| 179 | |
| 180 | Expected<MR::Mesh> doBooleanOperation( |
| 181 | Mesh&& meshACut, Mesh&& meshBCut, |
| 182 | std::vector<EdgePath>&& cutEdgesA, std::vector<EdgePath>&& cutEdgesB, |
| 183 | BooleanOperation operation, |
| 184 | const AffineXf3f* rigidB2A /*= nullptr */, |
| 185 | BooleanResultMapper* mapper /*= nullptr */, |
| 186 | bool mergeAllNonIntersectingComponents, |
| 187 | const BooleanInternalParameters& intParams ) |
| 188 | { |
| 189 | MR_TIMER; |
| 190 | |
| 191 | std::optional<FaceBitSet> aPart; |
| 192 | std::optional<FaceBitSet> bPart; |
| 193 | |
| 194 | bool needInsideA = operation == BooleanOperation::InsideA || operation == BooleanOperation::Intersection || operation == BooleanOperation::DifferenceBA; |
| 195 | bool needFlipA = operation == BooleanOperation::DifferenceBA; |
| 196 | bool needInsideB = operation == BooleanOperation::InsideB || operation == BooleanOperation::Intersection || operation == BooleanOperation::DifferenceAB; |
| 197 | bool needFlipB = operation == BooleanOperation::DifferenceAB; |
| 198 | bool onlyCutA = operation == BooleanOperation::InsideA || operation == BooleanOperation::OutsideA; |
| 199 | bool onlyCutB = operation == BooleanOperation::InsideB || operation == BooleanOperation::OutsideB; |
| 200 | bool needStitch = !onlyCutA && !onlyCutB; |
| 201 | if ( needStitch ) |
| 202 | assert( cutEdgesA.size() == cutEdgesB.size() ); |
| 203 | |
| 204 | // bPart |
| 205 | tbb::task_group taskGroup; |
| 206 | taskGroup.run( [&] () |
| 207 | { |
| 208 | if ( onlyCutA ) |
| 209 | return; |
| 210 | bPart = findMeshPart( meshBCut, cutEdgesB, meshACut, needInsideB, false, rigidB2A, mergeAllNonIntersectingComponents, intParams ); |
| 211 | } ); |
| 212 | // aPart |
| 213 | if ( !onlyCutB ) |
| 214 | aPart = findMeshPart( meshACut, cutEdgesA, meshBCut, needInsideA, true, rigidB2A, mergeAllNonIntersectingComponents, intParams ); |
| 215 | taskGroup.wait(); |
| 216 | |
| 217 | if ( ( onlyCutA && !aPart ) || |
| 218 | ( onlyCutB && !bPart ) || |
| 219 | ( ( needStitch ) && ( !bPart || !aPart ) ) ) |
| 220 | { |
| 221 | std::string s; |
| 222 | if ( !aPart && !onlyCutB ) |
| 223 | s += "Cannot separate mesh A to inside and outside parts, probably contours on mesh A are not closed or are not consistent."; |
| 224 | if ( !bPart && !onlyCutA ) |
| 225 | { |
| 226 | if ( !aPart && !onlyCutB ) |
| 227 | s += " "; |
| 228 | s += "Cannot separate mesh B to inside and outside parts, probably contours on mesh B are not closed or are not consistent."; |
| 229 | } |
| 230 | |
| 231 | return unexpected( s ); |
| 232 | } |
| 233 | |
| 234 | // no need update maps since we will update it during stitch |
| 235 | BooleanResultMapper::Maps* mapsBPtr = ( onlyCutB && mapper ) ? &mapper->maps[int( BooleanResultMapper::MapObject::B )] : nullptr; |
| 236 | taskGroup.run( [&] () |
| 237 | { |
no test coverage detected