Skip to content

Commit fbcb7f8

Browse files
committed
subdiv - evaluator fine-tuning
1 parent df4e353 commit fbcb7f8

File tree

1 file changed

+50
-54
lines changed

1 file changed

+50
-54
lines changed

src/slg/shapes/subdiv.cpp

Lines changed: 50 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -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 >
11661165
struct 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

Comments
 (0)