| 145 | } |
| 146 | |
| 147 | void updatePointPairs( PointPairs & pairs, |
| 148 | const MeshOrPointsXf& src, const MeshOrPointsXf& tgt, |
| 149 | float cosThreshold, float distThresholdSq, bool mutualClosest, bool ignoreBdTgts ) |
| 150 | { |
| 151 | MR_TIMER; |
| 152 | const AffineXf3f src2tgtXf( AffineXf3d( tgt.xf ).inverse() * AffineXf3d( src.xf ) ); |
| 153 | const AffineXf3f tgt2srcXf( AffineXf3d( src.xf ).inverse() * AffineXf3d( tgt.xf ) ); |
| 154 | |
| 155 | const VertCoords& srcPoints = src.obj.points(); |
| 156 | const VertCoords& tgtPoints = tgt.obj.points(); |
| 157 | |
| 158 | const auto srcNormals = src.obj.normals(); |
| 159 | const auto tgtNormals = tgt.obj.normals(); |
| 160 | |
| 161 | const auto srcWeights = src.obj.weights(); |
| 162 | const auto srcLimProjector = src.obj.limitedProjector(); |
| 163 | const auto tgtLimProjector = tgt.obj.limitedProjector(); |
| 164 | |
| 165 | pairs.active.clear(); |
| 166 | pairs.active.resize( pairs.vec.size(), true ); |
| 167 | |
| 168 | // calculate pairs |
| 169 | BitSetParallelForAll( pairs.active, [&] ( size_t idx ) |
| 170 | { |
| 171 | auto & res = pairs.vec[idx]; |
| 172 | const auto p0 = srcPoints[res.srcVertId]; |
| 173 | const auto pt = src2tgtXf( p0 ); |
| 174 | |
| 175 | MeshOrPoints::ProjectionResult prj; |
| 176 | // do not search for target point further than distance threshold |
| 177 | prj.distSq = distThresholdSq; |
| 178 | if ( res.tgtCloseVert ) |
| 179 | { |
| 180 | // start with old closest point ... |
| 181 | prj.point = tgtPoints[res.tgtCloseVert]; |
| 182 | if ( tgtNormals ) |
| 183 | prj.normal = tgtNormals( res.tgtCloseVert ); |
| 184 | prj.isBd = res.tgtOnBd; |
| 185 | prj.distSq = ( pt - prj.point ).lengthSq(); |
| 186 | prj.closestVert = res.tgtCloseVert; |
| 187 | } |
| 188 | // ... and try to find only closer one |
| 189 | tgtLimProjector( pt, prj ); |
| 190 | if ( !prj.closestVert ) |
| 191 | { |
| 192 | // no target point found within distance threshold |
| 193 | pairs.active.reset( idx ); |
| 194 | return; |
| 195 | } |
| 196 | const auto p1 = prj.point; |
| 197 | |
| 198 | // save the result |
| 199 | PointPair vp = res; |
| 200 | vp.distSq = prj.distSq; |
| 201 | vp.weight = srcWeights ? srcWeights( vp.srcVertId ) : 1.0f; |
| 202 | vp.tgtCloseVert = prj.closestVert; |
| 203 | vp.srcPoint = src.xf( p0 ); |
| 204 | vp.tgtPoint = tgt.xf( p1 ); |