{"record":{"id":"0c6f9fb7876b9797","repo":"stride3d/stride","slug":"control-points-apply-only-to-primitivetype-patchlist","errorCode":null,"errorMessage":"Control points apply only to PrimitiveType.PatchList","messagePattern":"Control points apply only to PrimitiveType\\.PatchList","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Graphics/PrimitiveTypeExtensions.cs","lineNumber":26,"sourceCode":"/// <summary>\n///   Defines extensions and helpers for <see cref=\"PrimitiveType\"/>.\n/// </summary>\npublic static class PrimitiveTypeExtensions\n{\n    /// <summary>\n    ///   Interpret the input vertex data type as a <strong>patch list</strong> for tesselation with a\n    ///   specific number of <strong>control points</strong>.\n    /// </summary>\n    /// <param name=\"controlPoints\">The number of control points. It must be a value in the range 1 to 32, inclusive.</param>\n    /// <returns>\n    ///   A <see cref=\"PrimitiveType\"/> value that represents a patch list with the specified number of control points.\n    /// </returns>\n    /// <exception cref=\"ArgumentException\">Control points apply only to <see cref=\"PrimitiveType.PatchList\"/>.</exception>\n    /// <exception cref=\"ArgumentOutOfRangeException\"><paramref name=\"controlPoints\"/> must be in the range 1 to 32, inclusive.</exception>\"\n    public static PrimitiveType ControlPointCount(this PrimitiveType primitiveType, int controlPoints)\n    {\n        if (primitiveType != PrimitiveType.PatchList)\n            throw new ArgumentException($\"Control points apply only to {nameof(PrimitiveType)}.{nameof(PrimitiveType.PatchList)}\", nameof(primitiveType));\n\n        const int MIN_CONTROL_POINTS = 1, MAX_CONTROL_POINTS = 32;\n\n        if (controlPoints < MIN_CONTROL_POINTS || controlPoints > MAX_CONTROL_POINTS)\n            throw new ArgumentOutOfRangeException(nameof(controlPoints), $\"Value must be in between {MIN_CONTROL_POINTS} and {MAX_CONTROL_POINTS}\");\n\n        return PrimitiveType.PatchList + controlPoints - 1;\n    }\n}\n","sourceCodeStart":8,"sourceCodeEnd":36,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Graphics/PrimitiveTypeExtensions.cs#L8-L36","documentation":"This extension method returns a PrimitiveType configured with a control-point count, which is meaningful only for tessellation (PrimitiveType.PatchList). Calling it on any other primitive type throws ArgumentException naming the 'primitiveType' parameter. A subsequent validation bounds control points to 1..32.","triggerScenarios":"Calling primitiveType.ControlPointCount(n) where primitiveType is not PatchList, e.g. TriangleList, LineStrip, or a default PrimitiveType value.","commonSituations":"Configuring tessellation stages with a generic primitive type; a settings/asset pipeline supplying a non-patch primitive type; misunderstanding that all PrimitiveType values accept control points.","solutions":["Use PrimitiveType.PatchList.ControlPointCount(n) when configuring hull/tessellation stages.","Only call ControlPointCount for tessellated pipelines; keep the plain primitive type otherwise.","Validate the primitive type from configuration before invoking."],"exampleFix":"// before\nvar type = PrimitiveType.TriangleList.ControlPointCount(3); // throws\n// after\nvar type = PrimitiveType.PatchList.ControlPointCount(3);","handlingStrategy":"type-guard","validationCode":"if (primitiveType != PrimitiveType.PatchList)\n    throw new InvalidOperationException(\"ControlPointCount requires PatchList\");\nif (controlPoints is < 1 or > 32)\n    throw new ArgumentOutOfRangeException(nameof(controlPoints));","typeGuard":"bool IsPatchList(PrimitiveType t) => t == PrimitiveType.PatchList;","tryCatchPattern":"try { type = primitiveType.ControlPointCount(n); }\ncatch (ArgumentException ex) { log.Error(\"control points need PatchList\", ex); }","preventionTips":["Call ControlPointCount only when setting up tessellation","Validate primitive type coming from config/assets","Remember control point range is 1..32"],"tags":["csharp","graphics","tessellation"],"backgroundTag":"invalid-enum-value","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}