@@ -1162,27 +1162,21 @@ struct Surface {
11621162
11631163// Helper to evaluate multi-layers data, like UV, Colors, Gamma, AOV.
11641164// EXTRACTOR is a callable type providing the coarse data for a given layer.
1165- template < typename EXTRACTOR >
11661165struct MultiLayerDataEvaluator {
11671166
1168- // Evaluated data are stored as smart pointers in a vector (one row per
1169- // layer), so that they are automatically freed if anything goes wrong
1170- // before the mesh is built. Each element of the vector is a buffer for a
1171- // layer. Eventually, the buffers have to be passed to ExtTriangleMesh
1172- // constructor, which takes ownership. In that way, they will be released.
1173-
1174- using DATA = std::remove_pointer_t <std::invoke_result_t <EXTRACTOR, u_int>>;
1175- using DATA_BUFFER = std::unique_ptr<DATA[]>;
1176-
1177- // Return float* if DATA is FloatAdapter
1178- // (for Alpha and AOV)
1179- using DATA_OUT = std::conditional_t <
1180- std::is_same_v<DATA, FloatAdapter>,
1181- float ,
1182- DATA
1183- >;
1167+ // Constructor
1168+ MultiLayerDataEvaluator (
1169+ const Surface& p_surface,
1170+ u_int p_layerSize,
1171+ const CoordVector& p_coords
1172+ ):
1173+ surface (p_surface),
1174+ layerSize (p_layerSize),
1175+ coords (p_coords)
1176+ {}
11841177
11851178 // Return type for evaluation
1179+ template <typename DATA_BUFFER, typename DATA_OUT>
11861180 struct EvaluatedLayers : std::vector<DATA_BUFFER> {
11871181
11881182 // Return-object constructor
@@ -1191,45 +1185,52 @@ struct MultiLayerDataEvaluator{
11911185 {}
11921186
11931187 // Return-object releaser
1194- std::array<DATA_OUT *, EXTMESH_MAX_DATA_COUNT>* release () {
1188+ std::array<DATA_OUT *, EXTMESH_MAX_DATA_COUNT>* releaseLayers () {
11951189 for (size_t layer = 0 ; layer < EXTMESH_MAX_DATA_COUNT; ++layer) {
1196- res [layer] = reinterpret_cast <DATA_OUT *>((*this )[layer].release ());
1190+ outBuffers [layer] = reinterpret_cast <DATA_OUT *>((*this )[layer].release ());
11971191 }
1198- return &res ;
1192+ return &outBuffers ;
11991193 }
12001194
1201- std::array<DATA_OUT *, EXTMESH_MAX_DATA_COUNT> res; // Released buffers
1195+ std::array<DATA_OUT *, EXTMESH_MAX_DATA_COUNT> outBuffers;
12021196 };
12031197
1204- // Constructor
1205- MultiLayerDataEvaluator (
1206- const Surface& p_surface,
1207- EXTRACTOR p_getLayerData,
1208- u_int p_layerSize,
1209- const CoordVector& p_coords
1210- ):
1211- surface (p_surface),
1212- getLayerData (p_getLayerData),
1213- layerSize (p_layerSize),
1214- coords (p_coords)
1215- {}
12161198
12171199 // Evaluator
1218- EvaluatedLayers evaluate () {
1219- EvaluatedLayers res (EXTMESH_MAX_DATA_COUNT);
1200+ template < typename EXTRACTOR >
1201+ auto evaluate (EXTRACTOR getLayerData) {
1202+
1203+ // Evaluated data are stored as smart pointers in a vector (one row per
1204+ // layer), so that they are automatically freed if anything goes wrong
1205+ // before the mesh is built. Each element of the vector is a buffer for a
1206+ // layer. Eventually, the buffers have to be passed to ExtTriangleMesh
1207+ // constructor, which takes ownership. In that way, they will be released.
1208+
1209+ using DATA_IN = std::remove_pointer_t <std::invoke_result_t <EXTRACTOR, u_int>>;
1210+ using DATA_BUFFER = std::unique_ptr<DATA_IN[]>;
1211+
1212+ // Return float* if DATA is FloatAdapter
1213+ // (for Alpha and AOV)
1214+ using DATA_OUT = std::conditional_t <
1215+ std::is_same_v<DATA_IN, FloatAdapter>, float , DATA_IN
1216+ >;
1217+
1218+ // Return object
1219+ EvaluatedLayers<DATA_BUFFER, DATA_OUT> res (EXTMESH_MAX_DATA_COUNT);
1220+
1221+ // Treatment
12201222 for (size_t layer = 0 ; layer < EXTMESH_MAX_DATA_COUNT; ++layer) {
1221- DATA * layerData = getLayerData (layer);
1223+ DATA_IN * layerData = getLayerData (layer);
12221224 if (layerData) {
12231225 auto interpolatedData = surface.Interpolate (layerData, layerSize);
1224- res[layer] = surface.Evaluate <DATA >(interpolatedData, coords);
1226+ res[layer] = surface.Evaluate <DATA_IN >(interpolatedData, coords);
12251227 }
12261228 }
12271229 return res;
12281230 }
12291231
12301232 const Surface& surface;
12311233 const size_t layerSize;
1232- const std::function<DATA*(u_int)> getLayerData;
12331234 const CoordVector& coords;
12341235
12351236};
@@ -1284,31 +1285,26 @@ ExtTriangleMesh *ApplySubdiv(
12841285 surface.EvaluatePositions (interpolatedPositions, tessCoords);
12851286 }
12861287
1288+ // Evaluate other primvars
1289+ MultiLayerDataEvaluator evaluator (surface, numMeshVertex, tessCoords);
1290+
12871291 // Evaluate UV
12881292 auto extractorUV = [&srcMesh](u_int layer) { return srcMesh->GetUVs (layer); };
1289- MultiLayerDataEvaluator
1290- EvaluatorUV (surface, extractorUV, numMeshVertex, tessCoords);
1291- auto tessUVs = EvaluatorUV.evaluate ();
1293+ auto tessUVs = evaluator.evaluate (extractorUV);
12921294
12931295 // Evaluate Colors
12941296 auto extractorCols = [&srcMesh](u_int layer) { return srcMesh->GetColors (layer); };
1295- MultiLayerDataEvaluator
1296- EvaluatorCols (surface, extractorCols, numMeshVertex, tessCoords);
1297- auto tessCols = EvaluatorCols.evaluate ();
1297+ auto tessCols = evaluator.evaluate (extractorCols);
12981298
12991299 // Evaluate Alphas
13001300 auto extractorAlphas = [&srcMesh](u_int layer)
13011301 { return (FloatAdapter*) srcMesh->GetAlphas (layer); };
1302- MultiLayerDataEvaluator
1303- EvaluatorAlphas (surface, extractorAlphas, numMeshVertex, tessCoords);
1304- auto tessAlphas = EvaluatorAlphas.evaluate ();
1302+ auto tessAlphas = evaluator.evaluate (extractorAlphas);
13051303
13061304 // Evaluate AOVs
13071305 auto extractorAOVs = [&srcMesh](u_int layer)
13081306 { return (FloatAdapter*) srcMesh->GetVertexAOVs (layer); };
1309- MultiLayerDataEvaluator
1310- EvaluatorAOVs (surface, extractorAOVs, numMeshVertex, tessCoords);
1311- auto tessAOVs = EvaluatorAOVs.evaluate ();
1307+ auto tessAOVs = evaluator.evaluate (extractorAOVs);
13121308
13131309 // Allocate the new mesh and release buffers (transfer ownership to new
13141310 // mesh)
@@ -1323,13 +1319,13 @@ ExtTriangleMesh *ApplySubdiv(
13231319 tessPoints.release (),
13241320 tessTriangles.release (),
13251321 tessNormals.release (),
1326- tessUVs.release (),
1327- tessCols.release (),
1328- tessAlphas.release ()
1322+ tessUVs.releaseLayers (),
1323+ tessCols.releaseLayers (),
1324+ tessAlphas.releaseLayers ()
13291325 );
13301326
13311327 // Handle AOVs
1332- auto tessAOVs_released = *tessAOVs.release ();
1328+ auto tessAOVs_released = *tessAOVs.releaseLayers ();
13331329 for (u_int i = 0 ; i < EXTMESH_MAX_DATA_COUNT; ++i) {
13341330 newMesh->SetVertexAOV (i, tessAOVs_released[i]);
13351331 }
0 commit comments