| 670 | } |
| 671 | |
| 672 | Expected<BooleanResultPoints> getBooleanPoints( const Mesh& meshA, const Mesh& meshB, |
| 673 | BooleanOperation operation, const AffineXf3f* rigidB2A ) |
| 674 | { |
| 675 | MR_TIMER; |
| 676 | |
| 677 | BooleanResultPoints result; |
| 678 | result.meshAVerts.resize( meshA.topology.lastValidVert() + 1 ); |
| 679 | result.meshBVerts.resize( meshB.topology.lastValidVert() + 1 ); |
| 680 | |
| 681 | const auto converters = getVectorConverters( meshA, meshB, rigidB2A ); |
| 682 | const auto intersections = findCollidingEdgeTrisPrecise( meshA, meshB, converters.toInt, rigidB2A ); |
| 683 | result.intersectionPoints.reserve( intersections.size() ); |
| 684 | |
| 685 | FaceBitSet collFacesA, collFacesB; |
| 686 | VertBitSet destVertsA, destVertsB, orgVertsA, orgVertsB; |
| 687 | collFacesA.resize( meshA.topology.lastValidFace() + 1 ); |
| 688 | collFacesB.resize( meshB.topology.lastValidFace() + 1 ); |
| 689 | orgVertsA.resize( meshA.topology.lastValidVert() + 1 ); |
| 690 | orgVertsB.resize( meshB.topology.lastValidVert() + 1 ); |
| 691 | destVertsA.resize( meshA.topology.lastValidVert() + 1 ); |
| 692 | destVertsB.resize( meshB.topology.lastValidVert() + 1 ); |
| 693 | for ( const auto& et : intersections ) |
| 694 | { |
| 695 | if ( et.isEdgeATriB() ) |
| 696 | { |
| 697 | gatherEdgeInfo( meshA.topology, et.edge, collFacesA, orgVertsA, destVertsA ); |
| 698 | collFacesB.set( et.tri() ); |
| 699 | |
| 700 | const auto isect = findEdgeTriIntersectionPoint( meshA, et.edge, meshB, et.tri(), converters, rigidB2A, EdgeTriComponent::Tri ); |
| 701 | result.intersectionPoints.emplace_back( isect ); |
| 702 | } |
| 703 | else |
| 704 | { |
| 705 | gatherEdgeInfo( meshB.topology, et.edge, collFacesB, orgVertsB, destVertsB ); |
| 706 | collFacesA.set( et.tri() ); |
| 707 | |
| 708 | const auto isect = findEdgeTriIntersectionPoint( meshB, et.edge, meshA, et.tri(), converters, rigidB2A, EdgeTriComponent::Edge ); |
| 709 | result.intersectionPoints.emplace_back( isect ); |
| 710 | } |
| 711 | } |
| 712 | |
| 713 | if ( orgVertsA.intersects( destVertsA ) || orgVertsB.intersects( destVertsB ) ) |
| 714 | { |
| 715 | // in this case we are not able to detect inside outside correctly |
| 716 | BooleanResultMapper mapper; |
| 717 | auto boolRes = MR::boolean( meshA, meshB, operation, rigidB2A, &mapper ); |
| 718 | if ( !boolRes.valid() ) |
| 719 | return unexpected( boolRes.errorString ); |
| 720 | |
| 721 | if ( !mapper.maps[int( BooleanResultMapper::MapObject::A )].old2newVerts.empty() ) |
| 722 | for ( auto v : meshA.topology.getValidVerts() ) |
| 723 | { |
| 724 | auto vn = mapper.maps[int( BooleanResultMapper::MapObject::A )].old2newVerts[v]; |
| 725 | if ( vn.valid() ) |
| 726 | result.meshAVerts.set( v ); |
| 727 | } |
| 728 | |
| 729 | if ( !mapper.maps[int( BooleanResultMapper::MapObject::B )].old2newVerts.empty() ) |
nothing calls this directly
no test coverage detected