Dupliquer et repositionner une zone de cuivre existante avec l'API Python de KiCad

Publié le 28 septembre 2026 par leZ

Clonez une zone de cuivre déjà posée, déplacez-la et faites-la pivoter autour d'un centre arbitraire — avec pcbnew ou l'API IPC de KiCad.

Avant / après : une zone de cuivre dupliquée par script, déplacée de 50 mm puis pivotée de 90° dans KiCad
La zone d'origine, puis sa copie déplacée et pivotée.

Une zone au contour complexe — un plan de masse découpé autour de plusieurs composants, un dégagement irrégulier — devient vite fastidieuse à reproduire ailleurs sur la board point par point. Comme pour un footprint, dupliquer la zone existante et la déplacer est plus rapide que de reconstruire le contour depuis zéro, en particulier pour reproduire un même motif à plusieurs endroits d’un panneau.

Dupliquer la zone

Duplicate clone le contour et toutes les propriétés de la zone :

import pcbnew
from pcbnew import Cast_to_ZONE

board = pcbnew.GetBoard()
original = list(board.Zones())[0]
clone = Cast_to_ZONE(original.Duplicate(False))
board.Add(clone)

⚠️ Comme pour FOOTPRINT.Duplicate, addToParentGroup est obligatoire (False si vous appelez board.Add vous-même) et le retour est un BOARD_ITEM générique — Cast_to_ZONE est nécessaire avant d’appeler une méthode propre à ZONE comme Rotate.

Toujours pas de méthode de duplication dédiée côté API IPC — même technique que pour dupliquer un footprint : copy.deepcopy puis effacement de l’identifiant :

import copy
from kipy import KiCad

board = KiCad().get_board()
original = board.get_zones()[0]
clone = copy.deepcopy(original)
clone.proto.ClearField("id")

⚠️ Testé : sans clone.proto.ClearField("id"), create_items (appelé plus bas) renvoie un objet qui ressemble à une zone créée, mais le nombre de zones sur la board ne change pas — même piège que pour la duplication de footprint.

Déplacer et faire pivoter la copie

Move et Rotate s’utilisent directement sur la zone dupliquée, en unités internes :

from pcbnew import VECTOR2I, FromMM, EDA_ANGLE, DEGREES_T

clone.Move(VECTOR2I(FromMM(50), FromMM(0)))
center = clone.GetBoundingBox().GetCenter()
clone.Rotate(center, EDA_ANGLE(90, DEGREES_T))

Testé : sur une zone à 8 sommets déplacée de 50 mm puis pivotée de 90° autour du centre de sa propre bounding box, le premier sommet passe de (223.52, 138.43) mm à (251.6125, 20.0025) mm — persiste identique après SaveBoard/LoadBoard.

Zone expose directement .move et .rotate, sans passer par .proto :

from kipy.geometry import Vector2, Angle

clone.move(Vector2.from_xy_mm(50, 0))
bbox = clone.bounding_box()
center = Vector2.from_xy(bbox.pos.x + bbox.size.x // 2, bbox.pos.y + bbox.size.y // 2)
clone.rotate(Angle.from_degrees(90), center)

board.create_items(clone)

Testé avec les mêmes valeurs que côté pcbnew (même board, même zone d’origine) : premier sommet identique au nanomètre près, (251.6125, 20.0025) mm — les deux API utilisent la même convention de rotation. Confirmé persistant après board.save() et relecture du fichier.

⚠️ Testé sur les deux API : la copie hérite du net de la zone d’origine (GND dans nos essais). Si ce n’est pas voulu, réassignez le net de la copie explicitement (clone.SetNet(...) / clone.net = Net(name=...)) avant de l’ajouter à la board.

Une zone dupliquée garde le statut de remplissage de l’originale au niveau des données, mais son polygone rempli ne se met pas à jour tout seul après un Move/Rotate — relancez un remplissage (voir le tuto création de zone) pour que le rendu suive la nouvelle position.

Pour aller plus loin

Cette combinaison Duplicate/Move/Rotate est la même brique que celle utilisée pour repositionner une piste, une via ou un texte existant — tous les BOARD_ITEM de pcbnew partagent ces trois méthodes. C’est la technique de base d’une panélisation automatique : dupliquer un sous-ensemble de zones (et de pistes, vias, footprints) une fois, puis le replacer à chaque position d’un panneau simplement en changeant le vecteur de déplacement et l’angle de rotation.