COMPO · 3.04 · FILL / OUTLINE / HOLES / CONVEXITY

Fill, outline,
holes и
convexity.

Paint-region topology формы: compound boundaries, outer/hole/island nesting, EVEN_ODD/NON_ZERO fill semantics, outline placement и structural convex/concave descriptors. 3.04 интерпретирует filled-region structure, но не владеет raw contour, silhouette readability, transform, visual mass или scene free-space.

ModuleCompo 3.04
Scoperegion topology / paint
Ownsholes / fill / convexity
PrimarylocalTopologyFit
GroupSHAPE_REGION_TOPOLOGY
Next3.05

Region topology, не новый silhouette owner

00 / module api

3.04 берёт closed boundaries и превращает их в filled-region structure: outer regions, holes, fill semantics, outline operation и convex/concave descriptors.

SCOPE

Compound region topology, fill rule, holes, outline placement, convexity/concavity descriptors и target-aware fit.

BOUNDARY

Raw contour → 3.02; silhouette readability → 3.03; transform → 3.05; scoring aggregation → 3.06.

FINALITY

LOCAL SHAPE REGION TOPOLOGY ONLY.

REGION ≠ VISUAL MASS. 3.04 знает, какие области заполнены и где есть holes, но не становится владельцем silhouette area, occupancy, density или perceived weight.

CompoundShapeGeometry

01 / compound geometry

Ring, donut, буква O, несколько disconnected filled components — это не новые primitive family. Они представлены boundary set + region graph + fill rule.

Compound

CompoundShapeGeometry {
  kind: "COMPOUND",
  boundaryRefs[],
  regionGraph,
  fillRule:
    "EVEN_ODD|NON_ZERO",
  outerRegionRefs[],
  holeRegionRefs[],
  exactness,
  provenance
}

Region graph

RegionNestingTree {
  nodes: [{
    boundaryRef,
    parentRef?,
    nestingDepth,
    windingDirection?,
    resolvedRole:
      "OUTER|HOLE|ISLAND|UNRESOLVED"
  }]
}
Hole identity is derived from fill semantics. Clockwise/CCW alone is evidence; it is not universally equivalent to OUTER/HOLE.

EVEN_ODD и NON_ZERO

02 / fill rules

Fill semantics должна быть явной. Иначе одинаковый набор contours может давать разные filled regions.

EVEN_ODD

Parity

for query point p: crossings = number of boundary crossings filled(p) = crossings % 2 == 1 orientation does not matter for parity itself
NON_ZERO

Winding sum

for query point p: windingSum = Σ signed winding contributions filled(p) = windingSum != 0 orientation participates in region semantics
NO DEFAULT SEMANTIC GUESS. Если imported compound path не сообщает fill rule, 3.04 возвращает unresolved fill semantics вместо автоматического выбора.

Outer, hole, island

03 / holes and nesting

Nested contours образуют дерево. При EVEN_ODD depth parity даёт alternating fill/hole/island. При NON_ZERO решающим становится winding accumulation.

DepthEVEN_ODDPossible semantic role
0filledOUTER
1emptyHOLE
2filledISLAND
3emptynested HOLE
holeCount componentCount nestingDepth = DESCRIPTORS They do not mean: fewer holes = better one component = better shallow nesting = better

Outline — derived band, не source mutation

04 / outline operation

Outline может идти по центру boundary, внутрь filled region или наружу. Width/style меняют derived paint region, но не исходные contour points.

NONE

No outline

Fill region only.

CENTER

Centered

Band extends both sides of source boundary.

INSIDE

Inside

Derived band constrained toward filled side.

OUTSIDE

Outside

Derived band expands outside filled region.

OutlineOperationDescriptor {
  sourceBoundaryRefs[],
  placement,
  width,
  derivedBandGeometryRef?,
  exactness,
  errorBound?,
  provenance
}
OUTLINE WIDTH ≠ VISUAL MASS OWNER. Topic 4 может позже использовать derived outline geometry как evidence для mass/occupancy, но 3.04 не публикует perceived-weight score.

Convexity без area ratio

05 / convexity

Чтобы не забирать Topic 4, convexity определяется structural geometry: sign-consistent turns/support behavior и stable reflex features, а не area(shape)/area(hull).

Polygonal exact

for ordered simple contour: turnSignᵢ = sign(cross(eᵢ,eᵢ₊₁)) ignore |turn| <= epsilon if all non-zero signs equal: convexityClass = CONVEX else: convexityClass = CONCAVE

Smooth / curved

preferred: exact support / turn adapter fallback: bounded polyline approximation + confidence + error provenance self-intersecting unresolved: INDETERMINATE
CONVEX ≠ BETTER. ConvexityClass — descriptor. Concave silhouette может быть более подходящим для explicit target.

Reflex events и indentation depth

06 / concavity features

Concavity может описываться без заполненной площади: stable reflex event + геометрическая глубина indentation относительно convex support/hull.

ConcavityFeature {
  qArc,
  positionN,
  reflexTurnDeg?,
  indentationDepthN,
  featureScaleN,
  exactness,
  confidence,
  provenance
}
reflexFeatureCount maxIndentationDepthN featureScaleN = structural descriptors NOT: concavityPenalty beautyScore globalWeight
Holes are different. Hole topology не считается «вогнутостью» outer boundary. Boundary concavity и region holes — разные признаки.

ShapeRegionTarget

07 / explicit target

Только target превращает region descriptors в fit-компоненты.

Target

ShapeRegionTarget {
  allowedFillRules?,
  holeCountRange?,
  maxNestingDepth?,
  allowedOutlineModes?,
  convexityPreference?:
    "CONVEX|CONCAVE|ANY",
  reflexFeatureCountRange?,
  indentationDepthRange?,
  requiredEvidencePolicy?
}

No target

holeCount → descriptor
fillRule → descriptor
outlinePlacement → descriptor
convexityClass → descriptor
concavityFeatures → descriptor

holeStructureFit = N/A
convexityFit = N/A
localTopologyFit = N/A

Composite-first handoff → 3.06

08 / canonical metric export

3.04 отдаёт один composite vote. Hole count, convexity class и indentation depth напрямую в scorer не голосуют.

PRIMARY

localTopologyFit

key:
  shape.region.localTopologyFit

owner:
  Compo3.04

scoringGroup:
  SHAPE_REGION_TOPOLOGY

composite: true
componentOf: null
independentVoteAllowed: false
COMPONENTS

Diagnostic by default

holeStructureFit
fillRuleFit
outlineModeFit
convexityFit

componentOf:
  shape.region.localTopologyFit
localTopologyFit = weightedMeanApplicable([ holeStructureFit, fillRuleFit, outlineModeFit, convexityFit ]) NO explicit ShapeRegionTarget → localTopologyFit = N/A

Validity и неоднозначность

09 / edge cases

Region topology нельзя «починить» эстетическим score.

CaseStatusPolicy
fill rule missing for ambiguous compound pathUNRESOLVEDcaller/import owner supplies semantics
hole boundary lies outside claimed outerINVALID RELATIONgeometry correction request
two boundaries overlap/coincideAMBIGUOUSexact boolean resolver or correction
self-intersecting unresolved contourINDETERMINATE CONVEXITYdo not force convex/concave
zero outline widthcanonical NONE or zero-band descriptorpolicy-driven normalization
holeCount target missingN/A fitnot zero

Owner исправляет своё

10 / correction routing

3.04 может изменить собственные paint/topology parameters, но contour geometry и transform остаются чужими.

Fill rule

3.04 may patch ShapePaintRef.

Outline

3.04 may derive band / change own placement.

Contour shape

→ 3.02 / 3.06 correction request.

Transform

→ Core / 3.05.

NO FOREIGN MUTATION. Convexity target mismatch не разрешает 3.04 двигать control points напрямую.

Визуальная лаборатория

11 / visual lab

Ring, nested island, convex/concave outer boundary и outline placement. Примеры не ранжируются.

A · RING / HOLE outer + hole · compound, not primitive B · NESTED ISLAND depth 0 fill · 1 hole · 2 island C · CONVEX / CONCAVE convexity is descriptor reflex events + indentation D · OUTLINE PLACEMENT CENTER reference INSIDE derived band OUTSIDE derived band paint-region topology ≠ visual mass · no area-based quality here

Reference topology tests

12 / deterministic tests

Проверяем fill rules, nesting parity, convexity classification, target gate, composite metadata и no-owner-theft.

Tests not run yet.

DATA FOR LAYOUT ENGINE

13 / machine contract

Machine-readable contract 3.04.

{
  "module": "Compo 3.04",
  "name": "shape_fill_outline_holes_convexity_concavity",
  "version": "1.1-corrective",
  "scope": "LOCAL_SHAPE_REGION_TOPOLOGY_PAINT_STRUCTURE_AND_CONVEXITY_INTERPRETATION",
  "consumes": [
    "Compo3.00.Shape",
    "Compo3.02.PathShapeGeometry or compatible closed boundary adapters",
    "Compo3.03.SilhouetteTopologyDescriptor?",
    "Compo3.01.PrimitiveToPathResult?",
    "GeometryToleranceContext?",
    "ShapeRegionTarget?"
  ],
  "provides": [
    "CompoundShapeGeometry",
    "ShapePaintRef",
    "FillTopologyDescriptor",
    "RegionNestingTree",
    "HoleDescriptor[]",
    "OutlineOperationDescriptor",
    "ConvexityDescriptor",
    "ConcavityFeature[]",
    "ShapeRegionFitResult",
    "MetricResult[shape.region.localTopologyFit]",
    "ShapeRegionCorrectionRequest[]"
  ],
  "owns_metrics": [
    "shape.region.holeStructureFit",
    "shape.region.fillRuleFit",
    "shape.region.outlineModeFit",
    "shape.region.convexityFit",
    "shape.region.localTopologyFit",
    "shape.region.confidence"
  ],
  "descriptors_only": [
    "shape.region.componentCount",
    "shape.region.holeCount",
    "shape.region.nestingDepth",
    "shape.region.fillRule",
    "shape.region.outlinePlacement",
    "shape.region.convexityClass",
    "shape.region.reflexFeatureCount",
    "shape.region.maxIndentationDepthN",
    "shape.region.concavityFeatures[]",
    "shape.region.regionGraph"
  ],
  "fill_rules": [
    "EVEN_ODD",
    "NON_ZERO"
  ],
  "outline_modes": [
    "NONE",
    "CENTER",
    "INSIDE",
    "OUTSIDE"
  ],
  "convexity_classes": [
    "CONVEX",
    "CONCAVE",
    "DEGENERATE",
    "INDETERMINATE"
  ],
  "metric_exports": {
    "primary_vote": {
      "key": "shape.region.localTopologyFit",
      "owner": "Compo3.04",
      "scoringGroup": "SHAPE_REGION_TOPOLOGY",
      "composite": true,
      "componentOf": null,
      "dependsOn": [
        "shape.region.holeStructureFit",
        "shape.region.fillRuleFit",
        "shape.region.outlineModeFit",
        "shape.region.convexityFit"
      ],
      "derivedFrom": [
        "shape.region.componentCount",
        "shape.region.holeCount",
        "shape.region.nestingDepth",
        "shape.region.convexityClass",
        "shape.region.reflexFeatureCount",
        "shape.region.maxIndentationDepthN"
      ],
      "independentVoteAllowed": false
    },
    "components": [
      {
        "key": "shape.region.holeStructureFit",
        "componentOf": "shape.region.localTopologyFit",
        "scoringGroup": "SHAPE_REGION_TOPOLOGY",
        "independentVoteAllowed": false
      },
      {
        "key": "shape.region.fillRuleFit",
        "componentOf": "shape.region.localTopologyFit",
        "scoringGroup": "SHAPE_REGION_TOPOLOGY",
        "independentVoteAllowed": false
      },
      {
        "key": "shape.region.outlineModeFit",
        "componentOf": "shape.region.localTopologyFit",
        "scoringGroup": "SHAPE_REGION_TOPOLOGY",
        "independentVoteAllowed": false
      },
      {
        "key": "shape.region.convexityFit",
        "componentOf": "shape.region.localTopologyFit",
        "scoringGroup": "SHAPE_REGION_TOPOLOGY",
        "independentVoteAllowed": false
      }
    ],
    "diagnostic_only": [
      "shape.region.componentCount",
      "shape.region.holeCount",
      "shape.region.nestingDepth",
      "shape.region.convexityClass",
      "shape.region.reflexFeatureCount",
      "shape.region.maxIndentationDepthN",
      "shape.region.concavityFeatures[]",
      "shape.region.confidence"
    ]
  },
  "metric_policy": {
    "primary_vote": "shape.region.localTopologyFit",
    "components": "DIAGNOSTIC_ONLY_BY_DEFAULT_WHEN_COMPOSITE_ACTIVE",
    "explicit_target_required": true,
    "no_target": "RETURN_DESCRIPTORS_AND_NA_SCORE",
    "convex_is_not_universally_better": true,
    "fewer_holes_is_not_universally_better": true,
    "outline_is_not_universally_better": true,
    "fill_rule_is_semantic_not_aesthetic_by_default": true
  },
  "compound_geometry": {
    "kind": "COMPOUND",
    "boundaryRefs": "closed boundary references",
    "regionGraph": "containment/nesting relations",
    "fillRule": "EVEN_ODD|NON_ZERO",
    "outerRegionRefs": "resolved filled outer regions",
    "holeRegionRefs": "resolved hole regions",
    "exactness": "EXACT|BOUNDED_APPROXIMATION",
    "provenance": "object"
  },
  "paint_ref": {
    "fillEnabled": "boolean",
    "fillStyleRef": "external paint/style reference; 3.04 does not own color harmony",
    "outlineEnabled": "boolean",
    "outlinePlacement": "NONE|CENTER|INSIDE|OUTSIDE",
    "outlineWidth": "explicit units or style preset",
    "outlineStyleRef": "external paint/style reference",
    "fillRule": "EVEN_ODD|NON_ZERO"
  },
  "convexity_policy": {
    "polygonal_exact": "all non-zero turn signs consistent => CONVEX; any reflex turn => CONCAVE",
    "smooth_or_curved": "use exact support/turn adapter when available; otherwise bounded polyline approximation with confidence",
    "self_intersecting": "INDETERMINATE unless an explicitly resolved simple filled region adapter is supplied",
    "holes": "filled region as a whole is not called convex when holes are present; boundary convexity and region convexity must be distinguished"
  },
  "concavity_features": {
    "reflexFeatureCount": "count of stable reflex events after tolerance-aware merging",
    "maxIndentationDepthN": "max normalized distance from concave boundary feature toward the convex support/hull representation",
    "featureScaleN": "local normalized indentation span",
    "provenance": "exact or bounded approximation"
  },
  "hard_constraints": [
    "raw contour segment geometry remains owned by Compo3.02",
    "silhouette readability/topology interpretation remains owned by Compo3.03",
    "object transform remains Core/Compo3.05",
    "fill rule determines filled-region semantics; winding direction alone must not be treated as hole identity",
    "rings/holes are compound region topology, not primitive aliases",
    "outline operation derives a new region/band and must not mutate the source contour",
    "outline width or filled area must not be converted into visual mass here",
    "silhouette area/occupancy/density remain Topic4",
    "scene free space remains Topic5",
    "global balance/hierarchy/eye-flow are not owned here",
    "convexity/concavity descriptors are not universal beauty signals",
    "no explicit target means localTopologyFit=N/A",
    "no beautyScore"
  ],
  "initial_heuristics": {
    "reflex_turn_epsilon_deg": {
      "value": 2.0,
      "provenance": "INITIAL_HEURISTIC"
    },
    "concavity_feature_merge_arc_fraction": {
      "value": 0.025,
      "provenance": "INITIAL_HEURISTIC"
    },
    "indentation_depth_noise_shortN": {
      "value": 0.0015,
      "provenance": "INITIAL_HEURISTIC"
    },
    "outline_offset_approx_error_shortN": {
      "value": 0.0005,
      "provenance": "INITIAL_HEURISTIC"
    }
  },
  "correction_policy": {
    "direct_foreign_contour_mutation": "FORBIDDEN",
    "invalid_outer_hole_relation": "request Compo3.02/3.06 geometry correction",
    "fill_rule_mismatch": "patch ShapeRegionTarget/ShapePaintRef only",
    "outline_mode_mismatch": "patch ShapePaintRef or request derived outline operation",
    "convexity_target_mismatch": "request bounded contour edit via Compo3.02/3.06",
    "transform_issue": "route to Compo3.05",
    "color_or_paint_harmony_issue": "route to external paint/color owner"
  },
  "deferred_inputs": [
    "Compo3.05 transformed world region",
    "Compo3.06 candidate generation and local shape aggregation",
    "Topic4 silhouette area/occupancy/visual mass",
    "Topic5 positive/negative space",
    "external paint/color harmony",
    "global balance/hierarchy/eye-flow"
  ],
  "recompute_when": [
    "boundary set changes",
    "boundary containment/nesting changes",
    "fill rule changes",
    "outline placement/width changes",
    "region target changes",
    "geometry tolerance/approximation policy changes"
  ],
  "finality": "LOCAL_SHAPE_REGION_TOPOLOGY_ONLY",
  "fill_rule_reference": {
    "EVEN_ODD": "filled iff crossing parity is odd",
    "NON_ZERO": "filled iff signed winding sum != 0",
    "orientation_note": "NON_ZERO uses signed contributions; opposite windings may cancel",
    "missing_fill_rule": "UNRESOLVED for ambiguous compound path"
  }
}
ARCHITECTURE CHECKPOINT · 3.04 OWNS COMPOUND REGION TOPOLOGY, FILL RULE, HOLE/ISLAND RESOLUTION, OUTLINE OPERATION AND TARGET-AWARE CONVEXITY/REGION FIT. RAW CONTOUR → 3.02. SILHOUETTE READABILITY → 3.03. OBJECT TRANSFORM → CORE / 3.05. GENERATION/AGGREGATION → 3.06. SILHOUETTE AREA / OCCUPANCY / VISUAL MASS → TOPIC 4. SCENE FREE SPACE → TOPIC 5. CONVEX ≠ BETTER.
VISITS / ...