Code Vonc

Sélections Supplétives

v 1.10

R13, R14, R15, R16, R17, R18, R19, R20, R21, R23 OSX Win

TéléchargerDownload
Faire un donMake a donation
Comment installer ?How to install ?
CommentairesComments

v 1.10 :
- Compatible R23.

v 1.9 :
- Correction des traductions.

v 1.8 :
- Ajout de la sélection par miroir.

v 1.7 :
- Ajout de la sélection aléatoire.
- Les boîtes de dialogues sont désormais asynchrones.
- Plus d'options pour la sélection par orientation.
- Traduction anglaise par Lubo Bezek.
- Traduction tchèque par Pavel Zoch.
- Correction de divers bogues.

v 1.5 :
- La sélection alternative affecte désormais les points.
- Ajout de la sélection des éléments adjacents.
- Ajout de la sélection de position.
- Ajout de la description des outils.


Lot de sélections en tout genre.

Copiez le dossier « vonc_selsup » dans le dossier « plugins » du répertoire de Cinéma 4D.




Sélectionner les polygones de même orientation

Sélectionne les polygones ayant la même orientation que le polygone sélectionné.


Sélectionner les éléments alternativement

Sélectionne les polygones ou les points à intervalle régulier à partir de la sélection active.
Sélectionner un polygone sur 2, 1 sur 3, 2 sur 4...


Sélectionner les polygones de même taille

Sélectionne tous les polygones ayant plus ou moins le même périmètre que le polygone sélectionné.


Sélectionner les triangles

Sélectionne tous les triangles de l'objet actif.


Sélectionner les quadrangles

Sélectionne tous les quadrangles de l'objet actif.


Sélectionner les n-gones

Sélectionne tous les n-gones de l'objet actif.


Sélectionner jusqu'à l'indice

Sélectionne tous les polygones ou tous les points d'indice inférieur au polygone/point sélectionné d'un objet ou d'une cerce (spline).


Sélectionner les contours

Sélectionne tous les contours de l'objet actif.


Sélectionner les éléments adjacents

Sélectionne les polygones ou les points adjacents à la sélection active.


Sélectionner jusqu'à la position

Sélectionne les points ou les polygones ayant une position supérieure ou inférieure à un point donné.


Sélection aléatoire

Sélectionne les points ou les polygones de façon aléatoire. Un facteur chance permet de sélectionner plus ou moins d'éléments. Il est également possible de sélectionner un nombre précis d'éléments.

Sélection par miroir

Sélectionne les points, arêtes ou polygones opposés par rapport à l'axe de l'objet.



Codes sourcesSources code

res/c4d_symbols.h

enum
{
	SS_SS_VAL			= 101,
	SS_SS_FER			= 102,
	
	SS_SELDIR_NOM		= 1001,
    SS_SELDIR_TOL		= 1002,
	SS_SELDIR_LIM		= 1003,
	SS_SELDIR_AID		= 1004,
	SS_SELDIR_NOR		= 1005,
	
	SS_SELNSN_NOM		= 1101,
	SS_SELNSN_SEL		= 1102,
	SS_SELNSN_SUR		= 1103,
	SS_SELNSN_DEC		= 1104,
	SS_SELNSN_AID		= 1105,
	
	SS_SELTAIL_NOM		= 1201,
	SS_SELTAIL_TOL		= 1202,
	SS_SELTAIL_INF		= 1203,
	SS_SELTAIL_SUP		= 1204,
	SS_SELTAIL_AID		= 1205,
	
	SS_SELTRI_NOM		= 1301,
	SS_SELTRI_AID		= 1302,
	
	SS_SELQUAD_NOM		= 1401,
	SS_SELQUAD_AID		= 1402,
	
	SS_SELNGON_NOM		= 1501,
	SS_SELNGON_AID		= 1502,
	
	SS_SELCON_NOM		= 1601,
	SS_SELCON_AID		= 1602,
	
	SS_SELIND_NOM		= 1701,
	SS_SELIND_AID		= 1702,
	
	SS_SELADJ_NOM		= 1801,
	SS_SELADJ_AID		= 1802,
	
	SS_SELPOS_NOM		= 1901,
	SS_SELPOS_TOL		= 1902,
	SS_SELPOS_AID		= 1903,
	
	SS_SELPIF_NOM		= 2001,
	SS_SELPIF_AID		= 2002,
	SS_SELPIF_SRC		= 2003,
	SS_SELPIF_QTE		= 2004,
	SS_SELPIF_CHC		= 2005,
	
	SS_SELMIR_NOM		= 2101,
	SS_SELMIR_AID		= 2102,
	SS_SELMIR_TOL		= 2103,
	SS_SELMIR_AJS		= 2104,
	
	SS_SELPTNU_NOM		= 2201,
	SS_SELPTNU_AID		= 2202,
	
	_DUMMY_ELEMENT_
}

res/strings_cs-CZ/c4d_strings.str

STRINGTABLE 
{
  SS_SS_VAL       "Pou\u017E\u00EDt";
  SS_SS_FER       "Zav\u0159\u00EDt";
  SS_SELDIR_NOM   "V\u00FDb\u011Br podle sm\u011Bru norm\u00E1ly polygonu";
  SS_SELDIR_TOL   "Tolerance :";
  SS_SELDIR_LIM   "Pouze spojen\u00E9 s v\u00FDb\u011Brem";
  SS_SELDIR_NOR   "Definice norm\u00E1ly";
  SS_SELDIR_AID   "Vybran\u00E9 budou polygony se stejn\u00FDm sm\u011Brem norm\u00E1l.";
  SS_SELNSN_NOM   "St\u0159\u00EDdav\u00FD v\u00FDb\u011Br bod\u016F/polygon\u016F";
  SS_SELNSN_SEL   "V\u00FDb\u011Br :";
  SS_SELNSN_SUR   "+ Mezera :";
  SS_SELNSN_DEC   "Posun :";
  SS_SELNSN_AID   "Vybere body nebo polygony v nastaven\u00FDch vzd\u00E1lenostech od aktu\u00E1ln\u00EDho v\u00FDb\u011Bru.";
  SS_SELTAIL_NOM  "V\u00FDb\u011Br podle velikosti polygonu";
  SS_SELTAIL_TOL  "Tolerance :";
  SS_SELTAIL_INF  "V\u010Detn\u011B men\u0161\u00EDch rozm\u011Br\u016F";
  SS_SELTAIL_SUP  "V\u010Detn\u011B v\u011Bt\u0161\u00EDch rozm\u011Br\u016F";
  SS_SELTAIL_AID  "Vybere v\u0161echny polygony v\u00EDcem\u00E9n\u011B shodn\u00E9 velikosti podle nastaven\u00E9 tolerance vybran\u00E9ho polygonu.";
  SS_SELTRI_NOM   "V\u00FDb\u011Br troj\u00FAheln\u00EDkov\u00FDch polygon\u016F";
  SS_SELTRI_AID   "Vybere v\u0161echny troj\u00FAheln\u00EDkov\u00E9 polygony aktivn\u00EDho objektu.";
  SS_SELQUAD_NOM  "V\u00FDb\u011Br \u010Dty\u0159\u00FAheln\u00EDkov\u00FDch polygon\u016F";
  SS_SELQUAD_AID  "Vybere v\u0161echny \u010Dty\u0159\u00FAheln\u00EDkov\u00E9 polygony aktivn\u00EDho objektu.";
  SS_SELNGON_NOM  "V\u00FDb\u011Br n-\u00FAheln\u00EDkov\u00FDch polygon\u016F";
  SS_SELNGON_AID  "Vybere v\u0161echny n-\u00FAheln\u00EDkov\u00E9 polygony aktivn\u00EDho objektu.";
  SS_SELCON_NOM   "V\u00FDb\u011Br obrysu";
  SS_SELCON_AID   "Vybere obrys aktivn\u00EDho objektu";
  SS_SELIND_NOM   "V\u00FDb\u011Br od za\u010D\u00E1tku po vybran\u00E9";
  SS_SELIND_AID   "Vybere v\u0161echny body/polygony od po\u010D\u00E1tku (index 0) a\u017E po vybran\u00FD bod/polygon objektu/k\u0159ivky";
  SS_SELADJ_NOM   "Zv\u011Bt\u0161it v\u00FDb\u011Br";
  SS_SELADJ_AID   "Zv\u011Bt\u0161\u00ED v\u00FDb\u011Br polygon\u016F \u010Di bod\u016F k aktivn\u00EDmu v\u00FDb\u011Bru.";
  SS_SELPOS_NOM   "V\u00FDb\u011Br z\u00E1visl\u00FD na pozici";
  SS_SELPOS_TOL   "Tolerance :";
  SS_SELPOS_AID   "Vybere body a nebo polygony s ni\u017E\u0161\u00ED a nebo vy\u0161\u0161\u00ED poz\u00EDc\u00ED, ne\u017E m\u00E1 vybran\u00FD element.";
  SS_SELPIF_NOM   "N\u00E1hodn\u00FD v\u00FDb\u011Br";
  SS_SELPIF_AID   "N\u00E1hodn\u011B vybere polygony nebo body aktivn\u00EDho objektu.";
  SS_SELPIF_SRC   "Po\u010D\u00E1tek n\u00E1h. :";
  SS_SELPIF_QTE   "Po\u010Det :";
  SS_SELPIF_CHC   "\u0160ance :";
  SS_SELMIR_NOM   "Zrcadlov\u00FD v\u00FDb\u011Br";
  SS_SELMIR_AID   "Vybere body,hrany nebo polygony na prot\u011Bj\u0161\u00ED ose.";
  SS_SELMIR_TOL   "Tolerance :";
  SS_SELMIR_AJS   "P\u0159idat k v\u00FDb\u011Bru";
  SS_SELPTNU_NOM  "Select unused points";
  SS_SELPTNU_AID  "Select the points unused by any polygon.";
}

res/strings_cz/c4d_strings.str

STRINGTABLE 
{
  SS_SS_VAL       "Pou\u017E\u00EDt";
  SS_SS_FER       "Zav\u0159\u00EDt";
  SS_SELDIR_NOM   "V\u00FDb\u011Br podle sm\u011Bru norm\u00E1ly polygonu";
  SS_SELDIR_TOL   "Tolerance :";
  SS_SELDIR_LIM   "Pouze spojen\u00E9 s v\u00FDb\u011Brem";
  SS_SELDIR_NOR   "Definice norm\u00E1ly";
  SS_SELDIR_AID   "Vybran\u00E9 budou polygony se stejn\u00FDm sm\u011Brem norm\u00E1l.";
  SS_SELNSN_NOM   "St\u0159\u00EDdav\u00FD v\u00FDb\u011Br bod\u016F/polygon\u016F";
  SS_SELNSN_SEL   "V\u00FDb\u011Br :";
  SS_SELNSN_SUR   "+ Mezera :";
  SS_SELNSN_DEC   "Posun :";
  SS_SELNSN_AID   "Vybere body nebo polygony v nastaven\u00FDch vzd\u00E1lenostech od aktu\u00E1ln\u00EDho v\u00FDb\u011Bru.";
  SS_SELTAIL_NOM  "V\u00FDb\u011Br podle velikosti polygonu";
  SS_SELTAIL_TOL  "Tolerance :";
  SS_SELTAIL_INF  "V\u010Detn\u011B men\u0161\u00EDch rozm\u011Br\u016F";
  SS_SELTAIL_SUP  "V\u010Detn\u011B v\u011Bt\u0161\u00EDch rozm\u011Br\u016F";
  SS_SELTAIL_AID  "Vybere v\u0161echny polygony v\u00EDcem\u00E9n\u011B shodn\u00E9 velikosti podle nastaven\u00E9 tolerance vybran\u00E9ho polygonu.";
  SS_SELTRI_NOM   "V\u00FDb\u011Br troj\u00FAheln\u00EDkov\u00FDch polygon\u016F";
  SS_SELTRI_AID   "Vybere v\u0161echny troj\u00FAheln\u00EDkov\u00E9 polygony aktivn\u00EDho objektu.";
  SS_SELQUAD_NOM  "V\u00FDb\u011Br \u010Dty\u0159\u00FAheln\u00EDkov\u00FDch polygon\u016F";
  SS_SELQUAD_AID  "Vybere v\u0161echny \u010Dty\u0159\u00FAheln\u00EDkov\u00E9 polygony aktivn\u00EDho objektu.";
  SS_SELNGON_NOM  "V\u00FDb\u011Br n-\u00FAheln\u00EDkov\u00FDch polygon\u016F";
  SS_SELNGON_AID  "Vybere v\u0161echny n-\u00FAheln\u00EDkov\u00E9 polygony aktivn\u00EDho objektu.";
  SS_SELCON_NOM   "V\u00FDb\u011Br obrysu";
  SS_SELCON_AID   "Vybere obrys aktivn\u00EDho objektu";
  SS_SELIND_NOM   "V\u00FDb\u011Br od za\u010D\u00E1tku po vybran\u00E9";
  SS_SELIND_AID   "Vybere v\u0161echny body/polygony od po\u010D\u00E1tku (index 0) a\u017E po vybran\u00FD bod/polygon objektu/k\u0159ivky";
  SS_SELADJ_NOM   "Zv\u011Bt\u0161it v\u00FDb\u011Br";
  SS_SELADJ_AID   "Zv\u011Bt\u0161\u00ED v\u00FDb\u011Br polygon\u016F \u010Di bod\u016F k aktivn\u00EDmu v\u00FDb\u011Bru.";
  SS_SELPOS_NOM   "V\u00FDb\u011Br z\u00E1visl\u00FD na pozici";
  SS_SELPOS_TOL   "Tolerance :";
  SS_SELPOS_AID   "Vybere body a nebo polygony s ni\u017E\u0161\u00ED a nebo vy\u0161\u0161\u00ED poz\u00EDc\u00ED, ne\u017E m\u00E1 vybran\u00FD element.";
  SS_SELPIF_NOM   "N\u00E1hodn\u00FD v\u00FDb\u011Br";
  SS_SELPIF_AID   "N\u00E1hodn\u011B vybere polygony nebo body aktivn\u00EDho objektu.";
  SS_SELPIF_SRC   "Po\u010D\u00E1tek n\u00E1h. :";
  SS_SELPIF_QTE   "Po\u010Det :";
  SS_SELPIF_CHC   "\u0160ance :";
  SS_SELMIR_NOM   "Zrcadlov\u00FD v\u00FDb\u011Br";
  SS_SELMIR_AID   "Vybere body,hrany nebo polygony na prot\u011Bj\u0161\u00ED ose.";
  SS_SELMIR_TOL   "Tolerance :";
  SS_SELMIR_AJS   "P\u0159idat k v\u00FDb\u011Bru";
  SS_SELPTNU_NOM  "Select unused points";
  SS_SELPTNU_AID  "Select the points unused by any polygon.";
}

res/strings_en-US/c4d_strings.str

STRINGTABLE 
{
  SS_SS_VAL       "Apply";
  SS_SS_FER       "Close";
  SS_SELDIR_NOM   "Select by polygon normal direction";
  SS_SELDIR_TOL   "Tolerance :";
  SS_SELDIR_LIM   "Limited to connected elements";
  SS_SELDIR_NOR   "Define normal";
  SS_SELDIR_AID   "Polygons with same normal direction will be selected.";
  SS_SELNSN_NOM   "Select points/polygons alternately";
  SS_SELNSN_SEL   "Selected :";
  SS_SELNSN_SUR   "+Gap :";
  SS_SELNSN_DEC   "Offset :";
  SS_SELNSN_AID   "Selects polygons or points at regular intervals from the current selection.";
  SS_SELTAIL_NOM  "Select by polygon size";
  SS_SELTAIL_TOL  "Tolerance :";
  SS_SELTAIL_INF  "Include smaller sizes";
  SS_SELTAIL_SUP  "Include larger sizes";
  SS_SELTAIL_AID  "Selects all polygons with more or less the same area as the selected polygon.";
  SS_SELTRI_NOM   "Select triangles";
  SS_SELTRI_AID   "Selects all triangles of the active object.";
  SS_SELQUAD_NOM  "Select quadrangles";
  SS_SELQUAD_AID  "Selects all quadrangles of the active object.";
  SS_SELNGON_NOM  "Select n-gons";
  SS_SELNGON_AID  "Selects all n-gons of the active object.";
  SS_SELCON_NOM   "Select the contour";
  SS_SELCON_AID   "Selects contour edges of the active object.";
  SS_SELIND_NOM   "Select from first to selected";
  SS_SELIND_AID   "Selects all points/polygons from first to selected point/polygon of active  polygon object or spline.";
  SS_SELADJ_NOM   "Grow selection";
  SS_SELADJ_AID   "Selects polygons or points adjacent to the active selection.";
  SS_SELPOS_NOM   "Select based on position";
  SS_SELPOS_TOL   "Tolerance :";
  SS_SELPOS_AID   "Selects points or polygons with a higher or lower position at a given point.";
  SS_SELPIF_NOM   "Random selection";
  SS_SELPIF_AID   "Selects polygons or points randomly.";
  SS_SELPIF_SRC   "Seed :";
  SS_SELPIF_QTE   "Quantity :";
  SS_SELPIF_CHC   "Chance :";
  SS_SELMIR_NOM   "Mirror selection";
  SS_SELMIR_AID   "Selects points, edges or polygons opposit to the axis.";
  SS_SELMIR_TOL   "Tolerance :";
  SS_SELMIR_AJS	  "Add to the selection";
  SS_SELPTNU_NOM  "Select unused points";
  SS_SELPTNU_AID  "Select the points unused by any polygon.";
}

res/strings_fr/c4d_strings.str

STRINGTABLE
{
	SS_SS_VAL			"Appliquer";
	SS_SS_FER			"Fermer";
	
	SS_SELDIR_NOM		"S\u00E9lectionner les polys de m\u00EAme orientation";
	SS_SELDIR_TOL		"Tol\u00E9rance :";
	SS_SELDIR_LIM		"Limiter aux \u00E9l\u00E9ments connect\u00E9s";
	SS_SELDIR_NOR		"D\u00E9finir la normale";
	SS_SELDIR_AID		"S\u00E9lectionne les polygones ayant la m\u00EAme normale que le polygone s\u00E9lectionn\u00E9.";
	
	SS_SELNSN_NOM		"S\u00E9lectionner les \u00E9l\u00E9ments alternativement";
	SS_SELNSN_SEL		"S\u00E9lectionner :";
	SS_SELNSN_SUR		"Sur :";
	SS_SELNSN_DEC		"D\u00E9calage :";
	SS_SELNSN_AID		"S\u00E9lectionne les polygones ou les points \u00E0 intervalle r\u00E9gulier \u00E0 partir de la s\u00E9lection active.";
	
	SS_SELTAIL_NOM		"S\u00E9lectionner les polys de m\u00EAme taille";
	SS_SELTAIL_TOL		"Tol\u00E9rance :";
	SS_SELTAIL_INF		"Inclure les tailles inf\u00E9rieures";
	SS_SELTAIL_SUP		"Inclure les tailles sup\u00E9rieures";
	SS_SELTAIL_AID		"S\u00E9lectionne tous les polygones ayant plus ou moins le m\u00EAme p\u00E9rim\u00E8tre que le polygone s\u00E9lectionn\u00E9.";
	
	SS_SELTRI_NOM		"S\u00E9lectionner les triangles";
	SS_SELTRI_AID		"S\u00E9lectionne tous les triangles de l'objet actif.";
	
	SS_SELQUAD_NOM		"S\u00E9lectionner les quadrangles";
	SS_SELQUAD_AID		"S\u00E9lectionne tous les quadrangles de l'objet actif.";
	
	SS_SELNGON_NOM		"S\u00E9lectionner les n-gones";
	SS_SELNGON_AID		"S\u00E9lectionne tous les n-gones de l'objet actif.";
	
	SS_SELCON_NOM		"S\u00E9lectionner les contours";
	SS_SELCON_AID		"S\u00E9lectionne tous les contours de l'objet actif.";
	
	SS_SELIND_NOM		"S\u00E9lectionner jusqu'\u00E0 l'indice";
	SS_SELIND_AID		"S\u00E9lectionne tous les polygones ou tous les points d'indice inf\u00E9rieur au polygone/point s\u00E9lectionn\u00E9 d'un objet ou d'une cerce (spline).";
	
	SS_SELADJ_NOM		"S\u00E9lectionner les \u00E9l\u00E9ments adjacents";
	SS_SELADJ_AID		"S\u00E9lectionne les polygones ou les points adjacents \u00E0 la s\u00E9lection active.";
	
	SS_SELPOS_NOM		"S\u00E9lectionner jusqu'\u00E0 la position";
	SS_SELPOS_TOL		"Tol\u00E9rance :";
	SS_SELPOS_AID		"S\u00E9lectionne les points ou les polygones ayant une position sup\u00E9rieure ou inf\u00E9rieure \u00E0 un point donn\u00E9.";
	
	SS_SELPIF_NOM		"S\u00E9lectionner les \u00E9l\u00E9ments al\u00E9atoirement";
	SS_SELPIF_AID		"S\u00E9lectionne des polygones ou des points de fa\u00E7on al\u00E9atoire.";
	SS_SELPIF_SRC		"Source :";
	SS_SELPIF_QTE		"Quantit\u00E9 :";
	SS_SELPIF_CHC		"Chances :";
	
	SS_SELMIR_NOM		"S\u00E9lectionner les \u00E9l\u00E9ments par miroir";
	SS_SELMIR_AID		"S\u00E9lectionne les points, ar\u00EAtes ou polygones oppos\u00E9s par rapport \u00E0 l'axe.";
	SS_SELMIR_TOL		"Tol\u00E9rance :";
	SS_SELMIR_AJS		"Ajouter \u00E0 la s\u00E9lection";
	
	SS_SELPTNU_NOM		"S\u00E9lectionner les points isol\u00E9s";
	SS_SELPTNU_AID		"S\u00E9lectionne les points n'appartenant \u00E0 aucun polygone.";
}

res/strings_fr-FR/c4d_strings.str

STRINGTABLE
{
	SS_SS_VAL			"Appliquer";
	SS_SS_FER			"Fermer";
	
	SS_SELDIR_NOM		"S\u00E9lectionner les polys de m\u00EAme orientation";
	SS_SELDIR_TOL		"Tol\u00E9rance :";
	SS_SELDIR_LIM		"Limiter aux \u00E9l\u00E9ments connect\u00E9s";
	SS_SELDIR_NOR		"D\u00E9finir la normale";
	SS_SELDIR_AID		"S\u00E9lectionne les polygones ayant la m\u00EAme normale que le polygone s\u00E9lectionn\u00E9.";
	
	SS_SELNSN_NOM		"S\u00E9lectionner les \u00E9l\u00E9ments alternativement";
	SS_SELNSN_SEL		"S\u00E9lectionner :";
	SS_SELNSN_SUR		"Sur :";
	SS_SELNSN_DEC		"D\u00E9calage :";
	SS_SELNSN_AID		"S\u00E9lectionne les polygones ou les points \u00E0 intervalle r\u00E9gulier \u00E0 partir de la s\u00E9lection active.";
	
	SS_SELTAIL_NOM		"S\u00E9lectionner les polys de m\u00EAme taille";
	SS_SELTAIL_TOL		"Tol\u00E9rance :";
	SS_SELTAIL_INF		"Inclure les tailles inf\u00E9rieures";
	SS_SELTAIL_SUP		"Inclure les tailles sup\u00E9rieures";
	SS_SELTAIL_AID		"S\u00E9lectionne tous les polygones ayant plus ou moins le m\u00EAme p\u00E9rim\u00E8tre que le polygone s\u00E9lectionn\u00E9.";
	
	SS_SELTRI_NOM		"S\u00E9lectionner les triangles";
	SS_SELTRI_AID		"S\u00E9lectionne tous les triangles de l'objet actif.";
	
	SS_SELQUAD_NOM		"S\u00E9lectionner les quadrangles";
	SS_SELQUAD_AID		"S\u00E9lectionne tous les quadrangles de l'objet actif.";
	
	SS_SELNGON_NOM		"S\u00E9lectionner les n-gones";
	SS_SELNGON_AID		"S\u00E9lectionne tous les n-gones de l'objet actif.";
	
	SS_SELCON_NOM		"S\u00E9lectionner les contours";
	SS_SELCON_AID		"S\u00E9lectionne tous les contours de l'objet actif.";
	
	SS_SELIND_NOM		"S\u00E9lectionner jusqu'\u00E0 l'indice";
	SS_SELIND_AID		"S\u00E9lectionne tous les polygones ou tous les points d'indice inf\u00E9rieur au polygone/point s\u00E9lectionn\u00E9 d'un objet ou d'une cerce (spline).";
	
	SS_SELADJ_NOM		"S\u00E9lectionner les \u00E9l\u00E9ments adjacents";
	SS_SELADJ_AID		"S\u00E9lectionne les polygones ou les points adjacents \u00E0 la s\u00E9lection active.";
	
	SS_SELPOS_NOM		"S\u00E9lectionner jusqu'\u00E0 la position";
	SS_SELPOS_TOL		"Tol\u00E9rance :";
	SS_SELPOS_AID		"S\u00E9lectionne les points ou les polygones ayant une position sup\u00E9rieure ou inf\u00E9rieure \u00E0 un point donn\u00E9.";
	
	SS_SELPIF_NOM		"S\u00E9lectionner les \u00E9l\u00E9ments al\u00E9atoirement";
	SS_SELPIF_AID		"S\u00E9lectionne des polygones ou des points de fa\u00E7on al\u00E9atoire.";
	SS_SELPIF_SRC		"Source :";
	SS_SELPIF_QTE		"Quantit\u00E9 :";
	SS_SELPIF_CHC		"Chances :";
	
	SS_SELMIR_NOM		"S\u00E9lectionner les \u00E9l\u00E9ments par miroir";
	SS_SELMIR_AID		"S\u00E9lectionne les points, ar\u00EAtes ou polygones oppos\u00E9s par rapport \u00E0 l'axe.";
	SS_SELMIR_TOL		"Tol\u00E9rance :";
	SS_SELMIR_AJS		"Ajouter \u00E0 la s\u00E9lection";
	
	SS_SELPTNU_NOM		"S\u00E9lectionner les points isol\u00E9s";
	SS_SELPTNU_AID		"S\u00E9lectionne les points n'appartenant \u00E0 aucun polygone.";
}

res/strings_us/c4d_strings.str

STRINGTABLE 
{
  SS_SS_VAL       "Apply";
  SS_SS_FER       "Close";
  SS_SELDIR_NOM   "Select by polygon normal direction";
  SS_SELDIR_TOL   "Tolerance :";
  SS_SELDIR_LIM   "Limited to connected elements";
  SS_SELDIR_NOR   "Define normal";
  SS_SELDIR_AID   "Polygons with same normal direction will be selected.";
  SS_SELNSN_NOM   "Select points/polygons alternately";
  SS_SELNSN_SEL   "Selected :";
  SS_SELNSN_SUR   "+Gap :";
  SS_SELNSN_DEC   "Offset :";
  SS_SELNSN_AID   "Selects polygons or points at regular intervals from the current selection.";
  SS_SELTAIL_NOM  "Select by polygon size";
  SS_SELTAIL_TOL  "Tolerance :";
  SS_SELTAIL_INF  "Include smaller sizes";
  SS_SELTAIL_SUP  "Include larger sizes";
  SS_SELTAIL_AID  "Selects all polygons with more or less the same area as the selected polygon.";
  SS_SELTRI_NOM   "Select triangles";
  SS_SELTRI_AID   "Selects all triangles of the active object.";
  SS_SELQUAD_NOM  "Select quadrangles";
  SS_SELQUAD_AID  "Selects all quadrangles of the active object.";
  SS_SELNGON_NOM  "Select n-gons";
  SS_SELNGON_AID  "Selects all n-gons of the active object.";
  SS_SELCON_NOM   "Select the contour";
  SS_SELCON_AID   "Selects contour edges of the active object.";
  SS_SELIND_NOM   "Select from first to selected";
  SS_SELIND_AID   "Selects all points/polygons from first to selected point/polygon of active  polygon object or spline.";
  SS_SELADJ_NOM   "Grow selection";
  SS_SELADJ_AID   "Selects polygons or points adjacent to the active selection.";
  SS_SELPOS_NOM   "Select based on position";
  SS_SELPOS_TOL   "Tolerance :";
  SS_SELPOS_AID   "Selects points or polygons with a higher or lower position at a given point.";
  SS_SELPIF_NOM   "Random selection";
  SS_SELPIF_AID   "Selects polygons or points randomly.";
  SS_SELPIF_SRC   "Seed :";
  SS_SELPIF_QTE   "Quantity :";
  SS_SELPIF_CHC   "Chance :";
  SS_SELMIR_NOM   "Mirror selection";
  SS_SELMIR_AID   "Selects points, edges or polygons opposit to the axis.";
  SS_SELMIR_TOL   "Tolerance :";
  SS_SELMIR_AJS	  "Add to the selection";
  SS_SELPTNU_NOM  "Select unused points";
  SS_SELPTNU_AID  "Select the points unused by any polygon.";
}

vonc_selsup.pyp

import os
import c4d
import math
import random
from c4d import plugins, bitmaps, gui, documents, Vector
from c4d.utils import GetAngle, Neighbor, VectorEqual, SendModelingCommand
from c4d.plugins import GeLoadString as txt
from math import isnan

doc = c4d.documents.GetActiveDocument()
MODULE_ID = 1028615
SEPARATEUR_ID = 1028614
ID_SELTRI = 1028616
ID_SELQUAD = 1028617
ID_SELNGON = 1028618
ID_SELDIR = 1028625
ID_SELNSN = 1028626
ID_SELCON = 1028627
ID_SELIND = 1028628
ID_SELTAIL = 1028644
ID_SELADJ = 1029578
ID_SELPOS = 1029579
ID_SELPIF = 1030552
ID_SELMIR = 1031153
ID_SELPTNU = 1035831

SS_SS_VAL = 101
SS_SS_FER = 102
SS_SELDIR_NOM = 1001
SS_SELDIR_TOL = 1002
SS_SELDIR_LIM = 1003
SS_SELDIR_AID = 1004
SS_SELDIR_NOR = 1005
SS_SELNSN_NOM = 1101
SS_SELNSN_SEL = 1102
SS_SELNSN_SUR = 1103
SS_SELNSN_DEC = 1104
SS_SELNSN_AID = 1105
SS_SELTAIL_NOM = 1201
SS_SELTAIL_TOL = 1202
SS_SELTAIL_INF = 1203
SS_SELTAIL_SUP = 1204
SS_SELTAIL_AID = 1205
SS_SELTRI_NOM = 1301
SS_SELTRI_AID = 1302
SS_SELQUAD_NOM = 1401
SS_SELQUAD_AID = 1402
SS_SELNGON_NOM = 1501
SS_SELNGON_AID = 1502
SS_SELCON_NOM = 1601
SS_SELCON_AID = 1602
SS_SELIND_NOM = 1701
SS_SELIND_AID = 1702
SS_SELADJ_NOM = 1801
SS_SELADJ_AID = 1802
SS_SELPOS_NOM = 1901
SS_SELPOS_TOL = 1902
SS_SELPOS_AID = 1903
SS_SELPIF_NOM = 2001
SS_SELPIF_AID = 2002
SS_SELPIF_SRC = 2003
SS_SELPIF_QTE = 2004
SS_SELPIF_CHC = 2005
SS_SELMIR_NOM = 2101
SS_SELMIR_AID = 2102
SS_SELMIR_TOL = 2103
SS_SELMIR_AJS = 2104
SS_SELPTNU_NOM = 2201
SS_SELPTNU_AID = 2202


class Seldir_Dialogue(gui.GeDialog) :
    tolerance = 0.17453
    limite = False
    norbool = False
    normale = Vector()

    def CreateLayout(self) :
        self.GroupBegin(100, c4d.BFH_SCALEFIT, 1, 1)
        self.GroupBorderSpace(5, 5, 5, 5)

        self.GroupBegin(101, c4d.BFH_SCALEFIT, 2, 1)
        self.AddStaticText(20, c4d.BFH_FIT, 0, 0, txt(SS_SELDIR_TOL))
        self.AddEditSlider(11, c4d.BFH_SCALEFIT)
        self.GroupEnd()

        self.GroupBegin(102, c4d.BFH_SCALEFIT, 1, 1)
        self.AddCheckbox(12, c4d.BFH_SCALEFIT, 0, 0, txt(SS_SELDIR_LIM))
        self.AddCheckbox(13, c4d.BFH_SCALEFIT, 0, 0, txt(SS_SELDIR_NOR))
        self.GroupEnd()

        self.GroupBegin(104, c4d.BFH_SCALEFIT, 3, 1)
        self.AddEditNumberArrows(130, c4d.BFH_SCALEFIT)
        self.AddEditNumberArrows(131, c4d.BFH_SCALEFIT)
        self.AddEditNumberArrows(132, c4d.BFH_SCALEFIT)
        self.GroupEnd()

        self.GroupBegin(103, c4d.BFH_SCALEFIT, 2, 1)
        self.AddButton(1, c4d.BFH_SCALEFIT, initw = 70, inith = 15, name = txt(SS_SS_VAL))
        self.AddButton(2, c4d.BFH_SCALEFIT, initw = 70, inith = 15, name = txt(SS_SS_FER))
        self.GroupEnd()

        self.GroupEnd()
        return True

    def InitValues(self) :
        self.SetTitle(txt(SS_SELDIR_NOM))
        self.SetDegree(11, self.tolerance, 0, 360)
        self.SetReal(130, 0.0, step=1.0)
        self.SetReal(131, 0.0, step=1.0)
        self.SetReal(132, 0.0, step=1.0)
        self.Enable(130, False)
        self.Enable(131, False)
        self.Enable(132, False)
        return True

    def Command(self, id, msg) :
        if id == 13 :
            nor = self.GetBool(13)
            self.Enable(130, nor)
            self.Enable(131, nor)
            self.Enable(132, nor)

        if id == c4d.DLG_OK :
            self.tolerance = self.GetReal(11)
            self.limite = self.GetBool(12)
            self.norbool = self.GetBool(13)
            self.normale = self.GetVector(130, 131, 132)

            doc = documents.GetActiveDocument()
            obj = doc.GetActiveObject()
            self.sel_dir(doc, obj)
        elif id == c4d.DLG_CANCEL :
            self.Close()
        return True


    def recup_norm(self, index, obj) :
        poly = obj.GetPolygon(index)
        pA = obj.GetPoint(poly.a)
        pB = obj.GetPoint(poly.b)
        pC = obj.GetPoint(poly.c)
        pD = obj.GetPoint(poly.d)
        normale = (pA - pC).Cross(pB - pD)
        normale.Normalize()
        return normale

    def verif(self, va, vb, tol) :
        angle = GetAngle(va, vb)
        if isnan(angle) :
            if VectorEqual(va, -vb) : return False
            return True
        if tol >= angle : return True
        else : return False

    def sel_dir(self, doc, obj) :
        if not obj : return
        if obj.GetType() != c4d.Opolygon : return
        if doc.GetMode() != c4d.Mpolygons : return

        bs = obj.GetPolygonS()
        nbsel = bs.GetCount()
        if nbsel == 0 and not self.norbool : return

        # dial = Seldir_Dialogue()
        # dial.Open(c4d.DLG_TYPE_MODAL)
        # if dial.annuler : return

        nbpol = obj.GetPolygonCount()
        normale_ref = Vector(0, 0, 0)

        doc.StartUndo()
        doc.AddUndo(c4d.UNDOTYPE_CHANGE_SELECTION, obj)

        premsel = 0
        for index, selec in enumerate(bs.GetAll(nbpol)) :
            if not selec: continue
            normale = self.recup_norm(index, obj)
            normale_ref += normale
            premsel = index

        if self.norbool : normale_ref = self.normale

        normale_ref.Normalize()
        tolerance = self.tolerance
        limite = self.limite

        for i in range(nbpol) :
            normale = self.recup_norm(i, obj)
            if self.verif(normale_ref, normale, tolerance) :
                bs.Select(i)

        if limite and nbsel :
            commande = c4d.ID_MODELING_FILL_SELECTION_TOOL
            mode = c4d.MODELINGCOMMANDMODE_POLYGONSELECTION
            params = c4d.BaseContainer()
            # for i in range(2160) :
                # params[i] = 167
            params[2157] = premsel #167
            SendModelingCommand(command=commande, list=[obj], mode=mode, bc=params, doc=doc, flags=c4d.MODELINGCOMMANDFLAGS_0)

        doc.EndUndo()
        c4d.EventAdd()
        c4d.CallCommand(12187) # Polygones


class Seldir(plugins.CommandData) :
    dialog = None

    def Execute(self, doc) :
        if self.dialog is None:
            self.dialog = Seldir_Dialogue()
        return self.dialog.Open(dlgtype=c4d.DLG_TYPE_ASYNC, pluginid=ID_SELDIR, defaulth=100, defaultw=70)

    def RestoreLayout(self, sec_ref):
        if self.dialog is None:
            self.dialog = Seldir_Dialogue()
        return self.dialog.Restore(pluginid=ID_SELDIR, secret=sec_ref)

class Selnsn_Dialogue(gui.GeDialog) :
    a = 1
    b = 2
    dec = 0

    def CreateLayout(self) :
        self.GroupBegin(10, c4d.BFH_SCALEFIT, 2, 3)
        self.GroupBorderSpace(5, 5, 5, 5)
        self.AddStaticText(20, c4d.BFH_SCALEFIT, 0, 0, txt(SS_SELNSN_SEL))
        self.AddEditNumberArrows(30, c4d.BFH_SCALEFIT)
        self.AddStaticText(21, c4d.BFH_SCALEFIT, 0, 0, txt(SS_SELNSN_SUR))
        self.AddEditNumberArrows(31, c4d.BFH_SCALEFIT)
        self.AddStaticText(22, c4d.BFH_SCALEFIT, 0, 0, txt(SS_SELNSN_DEC))
        self.AddEditNumberArrows(32, c4d.BFH_SCALEFIT)
        self.AddButton(1, c4d.BFH_SCALEFIT, initw = 70, inith = 15, name = txt(SS_SS_VAL))
        self.AddButton(2, c4d.BFH_SCALEFIT, initw = 70, inith = 15, name = txt(SS_SS_FER))
        self.GroupEnd()
        return True

    def InitValues(self) :
        self.SetTitle(txt(SS_SELNSN_NOM))
        self.SetLong(30, 1, 1)
        self.SetLong(31, 2, 1)
        return True

    def Command(self, id, msg) :
        if id == 1 :
            self.a = self.GetLong(30)
            self.b = self.GetLong(31)
            self.dec = self.GetLong(32)
            doc = documents.GetActiveDocument()
            obj = doc.GetActiveObject()
            self.sel_nsn(doc, obj)
        if id == 2 :
            self.Close()
        return True

    def verif(self, p, li, bs) :
        if not bs.IsSelected(p) : return False
        if li.IsSelected(p) : return False
        return True

    def point_voisin(self, pp, li, bs, n, obj) :
        if pp is None : return None

        polys = n.GetPointPolys(pp)
        points = []
        for poly in polys :
            poly = obj.GetPolygon(poly)
            points.extend([poly.a, poly.b, poly.c, poly.d])
        points = list(set(points))

        points_aretes = []
        for pt in points :
            arete = n.GetEdgePolys(pp, pt)
            if arete != (-1, -1) : points_aretes.append(pt)

        for pt in points_aretes :
            if not bs.IsSelected(pt) : continue
            if li.IsSelected(pt) : continue
            return pt

        return None

    def mono_voisin(self, pp, li, bs, n, obj) :
        if pp is None : return None
        pol = obj.GetPolygon(pp)

        nab = n.GetNeighbor(pol.a, pol.b, pp)
        if self.verif(nab, li, bs) : return nab

        nbc = n.GetNeighbor(pol.b, pol.c, pp)
        if self.verif(nbc, li, bs) : return nbc

        ncd = n.GetNeighbor(pol.c, pol.d, pp)
        if self.verif(ncd, li, bs) : return ncd

        nda = n.GetNeighbor(pol.d, pol.a, pp)
        if self.verif(nda, li, bs) : return nda

        return None

    def sel_nsn(self, doc, obj) :
        if not obj : return
        polygonal = obj.CheckType(c4d.Opolygon)
        cerce = obj.CheckType(c4d.Ospline)
        modePoints = doc.GetMode() == c4d.Mpoints
        modePolys = doc.GetMode() == c4d.Mpolygons
        if not polygonal and not cerce : return
        #if polygonal and not modePolys : return
        if cerce and not modePoints : return
        if not modePoints and not modePolys : return

        if modePolys :
            bs = obj.GetPolygonS()
            nbp = obj.GetPolygonCount()
        else :
            bs = obj.GetPointS()
            nbp = obj.GetPointCount()

        bs_total = bs.GetCount()
        if bs_total and bs_total < 2 : return

        # dial = Selnsn_Dialogue()
        # dial.Open(c4d.DLG_TYPE_MODAL)
        # if dial.annuler : return

        a = self.a
        b = self.b
        if (self.b < self.a) : b = a
        dec = self.dec % b

        doc.StartUndo()
        doc.AddUndo(c4d.UNDOTYPE_CHANGE_SELECTION, obj)

        #-----------
        if cerce :
            if not bs_total : bs.SelectAll(nbp-1)
            li = bs.GetClone()
            bs.DeselectAll()
            j = dec
            bs_sel = li.GetAll(nbp)
            for i, sel in enumerate(bs_sel) :
                if not sel :
                    j = dec
                    continue
                if (j%b) < a : bs.Select(i)
                j += 1

            doc.EndUndo()
            c4d.EventAdd()
            return
        #----------

        n = Neighbor()
        n.Init(obj)
        if not bs_total : bs.SelectAll(nbp)

        def traite(li, p, ordre) :
            if p != None :
                li.Select(p)
                ordre.append(p)

        def tour(pp) :
            ordre1 = []
            voisin = self.mono_voisin
            if modePoints : voisin = self.point_voisin

            pa = voisin(pp, li, bs, n, obj)
            traite(li, pp, ordre1)
            traite(li, pa, ordre1)

            po = voisin(pa, li, bs, n, obj)
            while (po != None) :
                traite(li, po, ordre1)
                po = voisin(po, li, bs, n, obj)

            ordre2 = []
            pb = voisin(pp, li, bs, n, obj)
            if pb != None :
                traite(li, pb, ordre2)
                po = voisin(pb, li, bs, n, obj)
            else : po = None
            while (po != None) :
                traite(li, po, ordre2)
                po = voisin(po, li, bs, n, obj)

            ordre1.reverse()
            ordre1.extend(ordre2)
            return ordre1

        ordre = []

        li = bs.GetClone()
        li.DeselectAll()
        bs_sel = bs.GetAll(nbp)
        for i, sel in enumerate(bs_sel) :
            if not sel : continue
            if li.IsSelected(i) : continue
            ordre.extend(tour(i))

        j = 0
        jmax = len(ordre)
        bs.DeselectAll()

        while (j < jmax) :
            for k in range(a) :
                s = j + k + dec
                if s >= jmax : break
                bs.Select(ordre[s])
            j += b

        doc.EndUndo()
        c4d.EventAdd()


class Selnsn(plugins.CommandData) :
    dialog = None

    def Execute(self, doc) :
        if self.dialog is None:
            self.dialog = Selnsn_Dialogue()
        return self.dialog.Open(dlgtype=c4d.DLG_TYPE_ASYNC, pluginid=ID_SELNSN, defaulth=100, defaultw=100)

    def RestoreLayout(self, sec_ref):
        if self.dialog is None:
            self.dialog = Selnsn_Dialogue()
        return self.dialog.Restore(pluginid=ID_SELNSN, secret=sec_ref)

class Seltri(plugins.CommandData) :
    def sel_tri(self, doc, obj) :
        if not obj : return
        if obj.GetType() != c4d.Opolygon : return
        ng = obj.GetNgonEdgesCompact()
        bs = obj.GetPolygonS()
        n = -1
        doc.StartUndo()
        doc.AddUndo(c4d.UNDOTYPE_CHANGE_SELECTION, obj)
        for p in ng :
            n += 1
            if p != 0: continue
            pol = obj.GetPolygon(n)
            if pol.c == pol.d : bs.Select(n)
        doc.EndUndo()
        c4d.EventAdd()
        c4d.CallCommand(12187) # Polygones

    def Execute(self, doc) :
        obj = doc.GetActiveObject()
        self.sel_tri(doc, obj)
        return True

class Selquad(plugins.CommandData) :
    def sel_quad(self, doc, obj):
        if not obj: return
        if obj.GetType() != c4d.Opolygon: return
        ng = obj.GetNgonEdgesCompact()
        bs = obj.GetPolygonS()
        n = -1
        doc.StartUndo()
        doc.AddUndo(c4d.UNDOTYPE_CHANGE_SELECTION, obj)
        for p in ng:
            n += 1
            if p != 0: continue
            pol = obj.GetPolygon(n)
            if pol.c != pol.d : bs.Select(n)
        doc.EndUndo()
        c4d.EventAdd()
        c4d.CallCommand(12187) # Polygones

    def Execute(self, doc) :
        obj = doc.GetActiveObject()
        self.sel_quad(doc, obj)
        return True

class Selngon(plugins.CommandData) :
    def sel_ngon(self, doc, obj) :
        if not obj: return
        if obj.GetType() != c4d.Opolygon: return
        ng = obj.GetNgonEdgesCompact()
        bs = obj.GetPolygonS()
        n = 0
        doc.StartUndo()
        doc.AddUndo(c4d.UNDOTYPE_CHANGE_SELECTION, obj)
        for p in ng:
            if p != 0: bs.Select(n)
            n += 1
        doc.EndUndo()
        c4d.EventAdd()
        c4d.CallCommand(12187) # Polygones

    def Execute(self, doc) :
        obj = doc.GetActiveObject()
        self.sel_ngon(doc, obj)
        return True

class Selcon(plugins.CommandData) :
    def sel_con(self, doc, obj):
        if not obj: return
        if obj.GetType() != c4d.Opolygon: return
        nb_pol = obj.GetPolygonCount()
        bs = c4d.BaseSelect()
        n = Neighbor()
        n.Init(obj)

        for i in range(nb_pol):
            pol = obj.GetPolygon(i)

            pa = pol.a
            pb = pol.b
            pc = pol.c
            pd = pol.d

            nab = n.GetNeighbor(pa, pb, i)
            nbc = n.GetNeighbor(pb, pc, i)
            ncd = n.GetNeighbor(pc, pd, i)
            nda = n.GetNeighbor(pd, pa, i)

            cotes = n.GetPolyInfo(i)["edge"]

            if nab == -1:
                bs.Select(cotes[0])
            if nbc == -1:
                bs.Select(cotes[1])
            if ncd == -1:
                if pc != pd: bs.Select(cotes[2])
            if nda == -1:
                bs.Select(cotes[3])

        doc.StartUndo()
        doc.AddUndo(c4d.UNDOTYPE_CHANGE_SELECTION, obj)
        obj.SetSelectedEdges(n, bs, 0)
        doc.EndUndo()
        c4d.EventAdd()
        c4d.CallCommand(16351) # Arêtes

    def Execute(self, doc) :
        obj = doc.GetActiveObject()
        self.sel_con(doc, obj)
        return True

class Selind(plugins.CommandData) :
    def sel_ind(self, doc, obj):
        if not obj : return
        if obj.GetType() != c4d.Opolygon and obj.GetType() != c4d.Ospline : return

        if c4d.IsCommandChecked(12187) and obj.GetType() == c4d.Opolygon : # Polygones
            bs = obj.GetPolygonS()
            nbp = obj.GetPolygonCount()
        else :
            bs = obj.GetPointS()
            nbp = obj.GetPointCount()

        nbsel = bs.GetCount()
        if nbsel == 0 : return

        doc.StartUndo()
        doc.AddUndo(c4d.UNDOTYPE_CHANGE_SELECTION, obj)

        for i, sel in enumerate(bs.GetAll(nbp)) :
            if not sel :
                bs.Select(i)
                continue
            break

        doc.EndUndo()
        c4d.EventAdd()

    def Execute(self, doc) :
        obj = doc.GetActiveObject()
        self.sel_ind(doc, obj)
        return True

class Seltail_Dialogue(gui.GeDialog) :
    tol = 0
    inf = False
    sup = False

    def CreateLayout(self) :
        self.GroupBegin(10, c4d.BFH_SCALEFIT, 1, 4)
        self.GroupBorderSpace(5, 5, 5, 5)
        self.GroupBegin(15, c4d.BFH_SCALEFIT, 2, 1)
        self.AddStaticText(16, c4d.BFH_SCALEFIT, name = txt(SS_SELTAIL_TOL))
        self.AddEditNumberArrows(11, c4d.BFH_SCALEFIT)
        self.GroupEnd()
        self.AddCheckbox(13, c4d.BFH_SCALEFIT, initw = 250, inith = 10, name = txt(SS_SELTAIL_INF))
        self.AddCheckbox(14, c4d.BFH_SCALEFIT, initw = 250, inith = 10, name = txt(SS_SELTAIL_SUP))
        self.GroupBegin(16, c4d.BFH_SCALEFIT, 2, 1)
        self.AddButton(1, c4d.BFH_SCALEFIT, initw = 70, inith = 15, name = txt(SS_SS_VAL))
        self.AddButton(2, c4d.BFH_SCALEFIT, initw = 70, inith = 15, name = txt(SS_SS_FER))
        self.GroupEnd()
        self.GroupEnd()
        return True

    def InitValues(self) :
        self.SetTitle(txt(SS_SELTAIL_NOM))
        self.SetPercent(11, 0.005, 0)
        return True

    def Command(self, id, msg) :
        if id == 1 :
            self.tol = self.GetReal(11)
            self.inf = self.GetBool(13)
            self.sup = self.GetBool(14)
            doc = documents.GetActiveDocument()
            obj = doc.GetActiveObject()
            self.sel_tail(doc, obj)
        if id == 2 :
            self.Close()
        return True

    def perim(self, i, obj) :
        poly = obj.GetPolygon(i)
        pA = obj.GetPoint(poly.a)
        pB = obj.GetPoint(poly.b)
        pC = obj.GetPoint(poly.c)
        pD = obj.GetPoint(poly.d)
        per = (pA - pB).GetLengthSquared() + (pB - pC).GetLengthSquared() + (pC - pD).GetLengthSquared() + (pD - pA).GetLengthSquared()
        return per

    def verif(self, ta, tb, tol, inf, sup) :
        tatol = ta*tol
        if inf :
            if tb <= (ta + tatol) :
                 return True

        if sup :
            if tb >= (ta - tatol) :
                 return True

        if tb <= (ta + tatol) :
            if tb >= (ta - tatol) :
                return True

        return False

    def sel_tail(self, doc, obj):
        if not obj : return
        if obj.GetType() != c4d.Opolygon : return
        if doc.GetMode() != c4d.Mpolygons : return

        bs = obj.GetPolygonS()
        nbsel = bs.GetCount()
        if nbsel == 0 : return

        # dial = Seltail_Dialogue()
        # dial.Open(c4d.DLG_TYPE_MODAL)
        # if dial.annuler : return

        nbpol = obj.GetPolygonCount()
        taille_ref = 0

        doc.StartUndo()
        doc.AddUndo(c4d.UNDOTYPE_CHANGE_SELECTION, obj)

        for index, selec in enumerate(bs.GetAll(nbpol)) :
            if not selec: continue
            taille = self.perim(index, obj)
            taille_ref += taille

        for i in range(nbpol) :
            taille = self.perim(i, obj)
            if self.verif(taille_ref, taille, self.tol, self.inf, self.sup) :
                bs.Select(i)

        doc.EndUndo()
        c4d.EventAdd()
        c4d.CallCommand(12187) # Polygones


class Seltail(plugins.CommandData) :
    dialog = None

    def Execute(self, doc) :
        if self.dialog is None:
            self.dialog = Seltail_Dialogue()
        return self.dialog.Open(dlgtype=c4d.DLG_TYPE_ASYNC, pluginid=ID_SELTAIL, defaulth=100, defaultw=70)

    def RestoreLayout(self, sec_ref):
        if self.dialog is None:
            self.dialog = Seltail_Dialogue()
        return self.dialog.Restore(pluginid=ID_SELTAIL, secret=sec_ref)

class Seladj(plugins.CommandData) :
    def sel_adj(self, doc, obj):
        if not obj : return
        modePoints = doc.GetMode() == c4d.Mpoints
        modePolys = doc.GetMode() == c4d.Mpolygons
        polygonal = obj.CheckType(c4d.Opolygon)
        cerce = obj.CheckType(c4d.Ospline)
        if not polygonal and not cerce : return
        if not modePoints and not modePolys : return
        if cerce and modePolys : return

        if polygonal :
            nb_pol = obj.GetPolygonCount()
            bs = obj.GetPolygonS()
            n = Neighbor()
            n.Init(obj)

        nb_pts = obj.GetPointCount()
        bs_p = obj.GetPointS()

        doc.StartUndo()
        doc.AddUndo(c4d.UNDOTYPE_CHANGE_SELECTION, obj)

        if modePolys :
            for i, sel in enumerate(bs.GetAll(nb_pol)):
                if not sel: continue
                pol = obj.GetPolygon(i)

                cotes = []
                cotes.extend(n.GetPointPolys(pol.a))
                cotes.extend(n.GetPointPolys(pol.b))
                cotes.extend(n.GetPointPolys(pol.c))
                cotes.extend(n.GetPointPolys(pol.d))

                for p in cotes :
                    bs.Select(p)

        else :
            if polygonal :
                for i, sel in enumerate(bs_p.GetAll(nb_pts)):
                    if not sel : continue
                    polys = n.GetPointPolys(i)
                    for poly in polys :
                        p = obj.GetPolygon(poly)
                        bs_p.Select(p.a)
                        bs_p.Select(p.b)
                        bs_p.Select(p.c)
                        bs_p.Select(p.d)
            else :
                for i, sel in enumerate(bs_p.GetAll(nb_pts)):
                    if not sel : continue
                    iP = i + 1
                    iM = i - 1
                    if iP < nb_pts : bs_p.Select(iP)
                    if iM >= 0 : bs_p.Select(iM)

        doc.EndUndo()
        c4d.EventAdd()

    def Execute(self, doc) :
        obj = doc.GetActiveObject()
        self.sel_adj(doc, obj)
        return True

class Selpos_Dialogue(gui.GeDialog) :
    tol = 0.001
    pos = Vector()
    Xcon = 0
    Ycon = 0
    Zcon = 0

    def CreateLayout(self) :
        self.GroupBegin(10, c4d.BFH_SCALEFIT, 1, 3)
        self.GroupBorderSpace(5, 5, 5, 5)

        self.GroupBegin(12, c4d.BFH_SCALEFIT, 5, 3)
        self.AddStaticText(20, c4d.BFH_SCALEFIT, name = "X")
        self.AddCheckbox(21, c4d.BFH_SCALEFIT, initw = 70, inith = 10, name = "<")
        self.AddCheckbox(22, c4d.BFH_SCALEFIT, initw = 70, inith = 10, name = ">")
        self.AddCheckbox(23, c4d.BFH_SCALEFIT, initw = 70, inith = 10, name = "=")
        self.AddEditNumberArrows(24, c4d.BFH_SCALEFIT, initw = 140)

        self.AddStaticText(30, c4d.BFH_SCALEFIT, name = "Y")
        self.AddCheckbox(31, c4d.BFH_SCALEFIT, initw = 70, inith = 10, name = "<")
        self.AddCheckbox(32, c4d.BFH_SCALEFIT, initw = 70, inith = 10, name = ">")
        self.AddCheckbox(33, c4d.BFH_SCALEFIT, initw = 70, inith = 10, name = "=")
        self.AddEditNumberArrows(34, c4d.BFH_SCALEFIT, initw = 140)

        self.AddStaticText(40, c4d.BFH_SCALEFIT, name = "Z")
        self.AddCheckbox(41, c4d.BFH_SCALEFIT, initw = 70, inith = 10, name = "<")
        self.AddCheckbox(42, c4d.BFH_SCALEFIT, initw = 70, inith = 10, name = ">")
        self.AddCheckbox(43, c4d.BFH_SCALEFIT, initw = 70, inith = 10, name = "=")
        self.AddEditNumberArrows(44, c4d.BFH_SCALEFIT, initw = 140)
        self.GroupEnd()

        self.GroupBegin(14, c4d.BFH_SCALEFIT, 2, 1)
        self.AddStaticText(13, c4d.BFH_SCALEFIT, name = txt(SS_SELPOS_TOL))
        self.AddEditNumberArrows(11, c4d.BFH_SCALEFIT)

        self.AddButton(1, c4d.BFH_SCALEFIT, initw = 70, inith = 15, name = txt(SS_SS_VAL))
        self.AddButton(2, c4d.BFH_SCALEFIT, initw = 70, inith = 15, name = txt(SS_SS_FER))
        self.GroupEnd()

        self.GroupEnd()
        return True

    def InitValues(self) :
        doc = documents.GetActiveDocument()
        obj = doc.GetActiveObject()
        self.pos = self.sel_pos(doc, obj, True)
        self.SetTitle(txt(SS_SELPOS_NOM))
        self.SetMeter(11, self.tol, 0)
        if self.pos is None : return True
        self.SetMeter(24, self.pos.x)
        self.SetMeter(34, self.pos.y)
        self.SetMeter(44, self.pos.z)
        return True

    def conditionneur(self, n) :
        inf = self.GetBool(n+1)
        sup = self.GetBool(n+2)
        ega = self.GetBool(n+3)
        # 0 : aucun, 1 : =, 2 : <, 3 : <=, 4 : >, 5 : >=
        return (inf*2 + sup*4 + ega)

    def Command(self, id, msg) :
        if id == 21 and self.GetBool(21) : self.SetBool(22, False)
        if id == 22 and self.GetBool(22) : self.SetBool(21, False)
        if id == 31 and self.GetBool(31) : self.SetBool(32, False)
        if id == 32 and self.GetBool(32) : self.SetBool(31, False)
        if id == 41 and self.GetBool(41) : self.SetBool(42, False)
        if id == 42 and self.GetBool(42) : self.SetBool(41, False)

        if id == 1 :
            self.tol = self.GetReal(11)
            if self.pos is None : return True
            self.pos.x = self.GetReal(24)
            self.pos.y = self.GetReal(34)
            self.pos.z = self.GetReal(44)
            self.Xcon = self.conditionneur(20)
            self.Ycon = self.conditionneur(30)
            self.Zcon = self.conditionneur(40)
            doc = documents.GetActiveDocument()
            obj = doc.GetActiveObject()
            self.sel_pos(doc, obj)
        if id == 2 :
            self.Close()
        return True

    def CoreMessage(self, id, msg) :
        if id == c4d.EVMSG_CHANGE :
            self.InitValues()
        return True

    def condition(self, pt, pos, con, tol) :
        if con == 1 :
            if pt < (pos+tol) and pt > (pos-tol) : return True
        elif con == 2 :
            if pt < (pos+tol) : return True
        elif con == 3 :
            if pt <= (pos+tol) : return True
        elif con == 4 :
            if pt > (pos-tol) : return True
        elif con == 5 :
            if pt >= (pos-tol) : return True
        return False

    def centrepoly(self, obj, i) :
        poly = obj.GetPolygon(i)
        centre = Vector()
        centre += obj.GetPoint(poly.a)
        centre += obj.GetPoint(poly.b)
        centre += obj.GetPoint(poly.c)
        if poly.c == poly.d :
            centre /= 3.0
        else :
            centre += obj.GetPoint(poly.d)
            centre *= 0.25
        return centre

    def sel_pos(self, doc, obj, init=False) :
        if not obj : return
        polygonal = obj.CheckType(c4d.Opolygon)
        cerce = obj.CheckType(c4d.Ospline)
        if not polygonal and not cerce : return
        mode = doc.GetMode()
        if mode != c4d.Mpoints and mode != c4d.Mpolygons : return
        if mode == c4d.Mpolygons and cerce : return

        if mode == c4d.Mpoints :
            points = True
            bs = obj.GetPointS()
        else :
            points = False
            bs = obj.GetPolygonS()

        nbsel = bs.GetCount()
        if points : nbp = obj.GetPointCount()
        else : nbp = obj.GetPolygonCount()

        if not init :
            doc.StartUndo()
            doc.AddUndo(c4d.UNDOTYPE_CHANGE_SELECTION, obj)

        centrepoly = self.centrepoly
        nb = 0
        p = Vector()
        pos_min = Vector()
        pos_max = Vector()

        for i, sel in enumerate(bs.GetAll(nbp)) :
            if not sel : continue

            if points : p = obj.GetPoint(i)
            else : p = centrepoly(obj, i)

            if p.x < pos_min.x or not nb : pos_min.x = p.x
            if p.y < pos_min.y or not nb : pos_min.y = p.y
            if p.z < pos_min.z or not nb : pos_min.z = p.z

            if p.x > pos_max.x or not nb : pos_max.x = p.x
            if p.y > pos_max.y or not nb : pos_max.y = p.y
            if p.z > pos_max.z or not nb : pos_max.z = p.z

            nb += 1
            if nb == nbp : break

        pos = (pos_min + pos_max) * 0.5

        if init : return pos

        # dial = Selpos_Dialogue(pos)
        # dial.Open(c4d.DLG_TYPE_MODAL)
        # if dial.annuler : return

        pos = self.pos
        tol = self.tol
        Xcon = self.Xcon
        Ycon = self.Ycon
        Zcon = self.Zcon
        condition = self.condition
        pt = Vector()

        for i in range(nbp) :
            if points :
                pt = obj.GetPoint(i)
            else :
                pt = centrepoly(obj, i)
            cond = 0
            res = 0
            if Xcon :
                cond += condition(pt.x, pos.x, Xcon, tol)
                res += 1
            if Ycon :
                cond += condition(pt.y, pos.y, Ycon, tol)
                res += 1
            if Zcon :
                cond += condition(pt.z, pos.z, Zcon, tol)
                res += 1
            if cond == res :
                bs.Select(i)

        doc.EndUndo()
        c4d.EventAdd()

class Selpos(plugins.CommandData) :
    dialog = None

    def Execute(self, doc) :
        if self.dialog is None:
            self.dialog = Selpos_Dialogue()
        return self.dialog.Open(dlgtype=c4d.DLG_TYPE_ASYNC, pluginid=ID_SELPOS, defaulth=100, defaultw=70)

    def RestoreLayout(self, sec_ref):
        if self.dialog is None:
            self.dialog = Selpos_Dialogue()
        return self.dialog.Restore(pluginid=ID_SELPOS, secret=sec_ref)

class Selmir_Dialogue(gui.GeDialog) :
    tol = 0.001
    Xcon = True
    Ycon = 0
    Zcon = 0
    ajsel = True

    def CreateLayout(self) :
        self.GroupBegin(10, c4d.BFH_SCALEFIT, 1, 3)
        self.GroupBorderSpace(5, 5, 5, 5)

        self.GroupBegin(12, c4d.BFH_SCALEFIT, 3, 1)
        self.AddCheckbox(21, c4d.BFH_SCALEFIT, initw = 20, inith = 0, name = "-X")
        self.AddCheckbox(22, c4d.BFH_SCALEFIT, initw = 20, inith = 0, name = "-Y")
        self.AddCheckbox(23, c4d.BFH_SCALEFIT, initw = 20, inith = 0, name = "-Z")
        self.GroupEnd()

        self.GroupBegin(15, c4d.BFH_SCALEFIT, 1, 1)
        self.AddCheckbox(24, c4d.BFH_SCALEFIT, initw = 0, inith = 0, name = txt(SS_SELMIR_AJS))
        self.GroupEnd()

        self.GroupBegin(14, c4d.BFH_SCALEFIT, 2, 1)
        self.AddStaticText(13, c4d.BFH_SCALEFIT, name = txt(SS_SELMIR_TOL))
        self.AddEditNumberArrows(11, c4d.BFH_SCALEFIT)

        self.AddButton(1, c4d.BFH_SCALEFIT, initw = 80, inith = 15, name = txt(SS_SS_VAL))
        self.AddButton(2, c4d.BFH_SCALEFIT, initw = 80, inith = 15, name = txt(SS_SS_FER))
        self.GroupEnd()

        self.GroupEnd()
        return True

    def InitValues(self) :
        doc = documents.GetActiveDocument()
        obj = doc.GetActiveObject()
        self.SetTitle(txt(SS_SELMIR_NOM))
        self.SetMeter(11, self.tol, 0.0001, step = 0.01)
        self.SetBool(21, self.Xcon)
        self.SetBool(22, self.Ycon)
        self.SetBool(23, self.Zcon)
        self.SetBool(24, self.ajsel)
        return True

    def Command(self, id, msg) :
        if id == 11 : self.tol = self.GetReal(11)
        if id == 21 : self.Xcon = self.GetBool(21)
        if id == 22 : self.Ycon = self.GetBool(22)
        if id == 23 : self.Zcon = self.GetBool(23)
        if id == 24 : self.ajsel = self.GetBool(24)
        if id == 1 :
            self.tol = self.GetReal(11)
            self.Xcon = self.GetBool(21)
            self.Ycon = self.GetBool(22)
            self.Zcon = self.GetBool(23)
            doc = documents.GetActiveDocument()
            obj = doc.GetActiveObject()
            self.sel_mir(doc, obj)
        if id == 2 :
            self.Close()
        return True

    def _texte(self, vec, tol) :
        vec *= tol
        vec.x = int(vec.x)
        vec.y = int(vec.y)
        vec.z = int(vec.z)
        p_txt = str(int(vec.x)) + "." + str(int(vec.y)) + "." + str(int(vec.z))
        return p_txt, vec

    def _centrepoly(self, obj, poly) :
        centre = Vector()
        centre += obj.GetPoint(poly.a)
        centre += obj.GetPoint(poly.b)
        centre += obj.GetPoint(poly.c)
        if poly.c == poly.d :
            centre /= 3.0
        else :
            centre += obj.GetPoint(poly.d)
            centre *= 0.25
        return centre

    def _centrearete(self, obj, poly, arete, polycen) :
        centre = Vector()
        aretes = [(poly.a, poly.b), (poly.b, poly.c), (poly.c, poly.d), (poly.d, poly.a)]
        for i in range(2) :
            centre += obj.GetPoint(aretes[arete][i])
        centre = centre * 0.5 + polycen
        return centre

    def sel_mir(self, doc, obj) :
        if not obj : return
        polygonal = obj.CheckType(c4d.Opolygon)
        cerce = obj.CheckType(c4d.Ospline)
        if not polygonal and not cerce : return
        mode = doc.GetMode()
        if cerce and mode != c4d.Mpoints : return

        if mode == c4d.Mpoints :
            bs = obj.GetPointS()
            tab = obj.GetAllPoints()
            nbp = obj.GetPointCount()

        elif mode == c4d.Medges :
            bs = obj.GetEdgeS()
            tab = obj.GetAllPolygons()
            nbp = obj.GetPolygonCount()

        elif mode == c4d.Mpolygons :
            bs = obj.GetPolygonS()
            tab = obj.GetAllPolygons()
            nbp = obj.GetPolygonCount()

        else :
            return

        if not bs or not nbp : return
        nbsel = bs.GetCount()
        if not nbsel : return

        dic = {}
        liste = []
        tol = self.tol
        itol = 1.0 / tol
        Xcon = self.Xcon
        Ycon = self.Ycon
        Zcon = self.Zcon
        Mpolys = c4d.Mpolygons
        Maretes = c4d.Medges
        _centrepoly = self._centrepoly
        _centrearete = self._centrearete
        _texte = self._texte

        for i, p in enumerate(tab) :
            if mode == Maretes :
                polycen = _centrepoly(obj, p)
                for j in range(4) :
                    pt = _centrearete(obj, p, j, polycen)
                    p_txt, vec = _texte(pt, itol)
                    if (p_txt in dic) : dic[p_txt].append(i*4 + j)
                    else : dic[p_txt] = [i*4 + j]
                    liste.append(vec)
            else :
                if mode == Mpolys : pt = _centrepoly(obj, p)
                else : pt = p
                p_txt, vec = _texte(pt, itol)
                if (p_txt in dic) : dic[p_txt].append(i)
                else : dic[p_txt] = [i]
                liste.append(vec)

        doc.StartUndo()
        doc.AddUndo(c4d.UNDOTYPE_CHANGE_SELECTION, obj)

        if self.ajsel : bsAct = bs
        else :
            bsAct = bs.GetClone()
            bs.DeselectAll()

        if mode == Maretes : nbp = nbp * 4 + 4

        for i, sel in enumerate(bsAct.GetAll(nbp)) :
            if not sel : continue

            vec = liste[i]
            if Xcon : vec.x *= -1
            if Ycon : vec.y *= -1
            if Zcon : vec.z *= -1
            p_txt = str(int(vec.x)) + "." + str(int(vec.y)) + "." + str(int(vec.z))

            try :
                js = dic[p_txt]
            except KeyError :
                pass
            else :
                for j in js :
                    bs.Select(j)

        if mode == Maretes :
            obj.ValidateEdgeSelection(bs)

        doc.EndUndo()
        c4d.EventAdd()

class Selmir(plugins.CommandData) :
    dialog = None

    def Execute(self, doc) :
        if self.dialog is None:
            self.dialog = Selmir_Dialogue()
        return self.dialog.Open(dlgtype=c4d.DLG_TYPE_ASYNC, pluginid=ID_SELMIR, defaulth=80, defaultw=100)

    def RestoreLayout(self, sec_ref):
        if self.dialog is None:
            self.dialog = Selmir_Dialogue()
        return self.dialog.Restore(pluginid=ID_SELMIR, secret=sec_ref)


class Selpif_Dialogue(gui.GeDialog) :
    src = 123456
    chc = 0
    bool_src = False
    qte = 10
    bool_qte = False

    def CreateLayout(self) :
        self.GroupBegin(100, c4d.BFH_SCALEFIT, 1, 1)
        self.GroupBorderSpace(5, 5, 5, 5)

        self.GroupBegin(101, c4d.BFH_SCALEFIT, 2, 2)
        self.AddCheckbox(12, c4d.BFH_SCALEFIT, initw = 0, inith = 0, name = txt(SS_SELPIF_SRC))
        self.AddEditNumberArrows(11, c4d.BFH_SCALEFIT)
        self.AddCheckbox(16, c4d.BFH_SCALEFIT, initw = 0, inith = 0, name = txt(SS_SELPIF_QTE))
        self.AddEditNumberArrows(15, c4d.BFH_SCALEFIT)
        self.AddStaticText(13, c4d.BFH_SCALEFIT, name = txt(SS_SELPIF_CHC))
        self.AddEditNumberArrows(14, c4d.BFH_SCALEFIT)
        self.GroupEnd()

        self.GroupBegin(102, c4d.BFH_SCALEFIT, 2, 2)
        self.AddButton(1, c4d.BFH_SCALEFIT, initw = 70, inith = 15, name = txt(SS_SS_VAL))
        self.AddButton(2, c4d.BFH_SCALEFIT, initw = 70, inith = 15, name = txt(SS_SS_FER))
        self.GroupEnd()

        self.GroupEnd()
        return True

    def InitValues(self) :
        self.SetTitle(txt(SS_SELPIF_NOM))
        self.SetLong(11, self.src)
        self.SetBool(12, self.bool_src)
        self.SetLong(15, self.qte, 0)
        self.SetBool(16, self.bool_qte)
        self.SetLong(14, self.chc)
        self.Enable(11, self.bool_src)
        self.Enable(15, self.bool_qte)
        self.Enable(14, not self.bool_qte)
        self.Enable(11, self.bool_src)
        return True

    def Command(self, id, msg) :
        if id == 12 : self.Enable(11, self.GetBool(12))
        if id == 16 :
            self.Enable(15, self.GetBool(16))
            self.Enable(14, not self.GetBool(16))

        if id == 1 :
            self.src = self.GetLong(11)
            self.bool_src = self.GetBool(12)
            self.qte = self.GetLong(15)
            self.bool_qte = self.GetBool(16)
            self.chc = self.GetLong(14)
            doc = documents.GetActiveDocument()
            obj = doc.GetActiveObject()
            self.sel_pif(doc, obj)
        if id == 2 :
            self.Close()
        return True

    def sel_pif(self, doc, obj) :
        if not obj : return
        polygonal = obj.CheckType(c4d.Opolygon)
        cerce = obj.CheckType(c4d.Ospline)
        if not polygonal and not cerce : return
        mode = doc.GetMode()
        if mode != c4d.Mpoints and mode != c4d.Mpolygons : return
        if mode == c4d.Mpolygons and cerce : return

        if mode == c4d.Mpoints :
            points = True
            bs = obj.GetPointS()
        else :
            points = False
            bs = obj.GetPolygonS()

        nbsel = bs.GetCount()
        if points : nbp = obj.GetPointCount()
        else : nbp = obj.GetPolygonCount()

        doc.StartUndo()
        doc.AddUndo(c4d.UNDOTYPE_CHANGE_SELECTION, obj)
        src = self.src
        chc = abs(self.chc) + 1
        qte = self.qte
        if qte > nbp : qte = nbp
        bs.DeselectAll()

        if self.bool_src : random.seed(src)

        if self.bool_qte :
            liste = [0] * nbp
            for i in range(qte) : liste[i] = 1
            random.shuffle(liste)
            bs.SetAll(liste)

        else :
            if self.chc > 0 :
                for i in range(nbp) :
                    pif = random.randint(0, chc)
                    if pif : bs.Select(i)
            else :
                for i in range(nbp) :
                    pif = random.randint(0, chc)
                    if not pif : bs.Select(i)

        doc.EndUndo()
        c4d.EventAdd()

class Selpif(plugins.CommandData) :
    dialog = None

    def Execute(self, doc) :
        if self.dialog is None:
            self.dialog = Selpif_Dialogue()
        return self.dialog.Open(dlgtype=c4d.DLG_TYPE_ASYNC, pluginid=ID_SELPIF, defaulth=100, defaultw=70)

    def RestoreLayout(self, sec_ref):
        if self.dialog is None:
            self.dialog = Selpif_Dialogue()
        return self.dialog.Restore(pluginid=ID_SELPIF, secret=sec_ref)

class Selptnu(plugins.CommandData) :
    def sel_ptnu(self, doc, obj):
        if not obj: return
        if not obj.CheckType(c4d.Opoint) : return
        pols = obj.GetAllPolygons()
        bs = obj.GetPointS()
        doc.StartUndo()
        doc.AddUndo(c4d.UNDOTYPE_CHANGE_SELECTION, obj)
        bs.SelectAll(obj.GetPointCount() - 1)
        for p in pols :
            bs.Deselect(p.a)
            bs.Deselect(p.b)
            bs.Deselect(p.c)
            bs.Deselect(p.d)
        doc.EndUndo()
        c4d.EventAdd()
        c4d.CallCommand(12139) # Points

    def Execute(self, doc) :
        obj = doc.GetActiveObject()
        self.sel_ptnu(doc, obj)
        return True

class SelSup(plugins.CommandData) :
    pass

def icone(nom) :
    bmp = bitmaps.BaseBitmap()
    dir, file = os.path.split(__file__)
    fn = os.path.join(dir, "res", nom)
    bmp.InitWith(fn)
    return bmp

if __name__ == "__main__":
    plugins.RegisterCommandPlugin(id=ID_SELNSN, str = "#$00" + txt(SS_SELNSN_NOM), info = 0, help = txt(SS_SELNSN_AID), dat = Selnsn(), icon = icone("selnsn.tif"))
    plugins.RegisterCommandPlugin(id=ID_SELADJ, str = "#$01" + txt(SS_SELADJ_NOM), info = 0, help = txt(SS_SELADJ_AID), dat = Seladj(), icon = icone("seladj.tif"))
    plugins.RegisterCommandPlugin(id=ID_SELPIF, str = "#$02" + txt(SS_SELPIF_NOM), info = 0, help = txt(SS_SELPIF_AID), dat = Selpif(), icon = icone("selpif.tif"))
    plugins.RegisterCommandPlugin(id=ID_SELMIR, str = "#$03" + txt(SS_SELMIR_NOM), info = 0, help = txt(SS_SELMIR_AID), dat = Selmir(), icon = icone("selmir.tif"))
    plugins.RegisterCommandPlugin(id=ID_SELDIR, str = "#$04" + txt(SS_SELDIR_NOM), info = 0, help = txt(SS_SELDIR_AID), dat = Seldir(), icon = icone("seldir.tif"))
    plugins.RegisterCommandPlugin(id=ID_SELTAIL, str = "#$05" + txt(SS_SELTAIL_NOM), info = 0, help = txt(SS_SELTAIL_AID), dat = Seltail(), icon = icone("seltail.tif"))
    plugins.RegisterCommandPlugin(id=ID_SELTRI, str = "#$06" + txt(SS_SELTRI_NOM), info = 0, help = txt(SS_SELTRI_AID), dat = Seltri(), icon = icone("seltri.tif"))
    plugins.RegisterCommandPlugin(id=ID_SELQUAD, str = "#$07" + txt(SS_SELQUAD_NOM), info = 0, help = txt(SS_SELQUAD_AID), dat = Selquad(), icon = icone("selquad.tif"))
    plugins.RegisterCommandPlugin(id=ID_SELNGON, str = "#$08" + txt(SS_SELNGON_NOM), info = 0, help = txt(SS_SELNGON_AID), dat = Selngon(), icon = icone("selngon.tif"))
    plugins.RegisterCommandPlugin(id=ID_SELCON, str = "#$09" + txt(SS_SELCON_NOM), info = 0, help = txt(SS_SELCON_AID), dat = Selcon(), icon = icone("selcon.tif"))
    plugins.RegisterCommandPlugin(id=ID_SELIND, str = "#$10" + txt(SS_SELIND_NOM), info = 0, help = txt(SS_SELIND_AID), dat = Selind(), icon = icone("selind.tif"))
    plugins.RegisterCommandPlugin(id=ID_SELPOS, str = "#$11" + txt(SS_SELPOS_NOM), info = 0, help = txt(SS_SELPOS_AID), dat = Selpos(), icon = icone("selpos.tif"))
    plugins.RegisterCommandPlugin(id=ID_SELPTNU, str = "#$13" + txt(SS_SELPTNU_NOM), info = 0, help = txt(SS_SELPTNU_AID), dat = Selptnu(), icon = icone("selptnu.tif"))
    plugins.RegisterCommandPlugin(id=SEPARATEUR_ID, str = "#$14--", info = 0, help = "vonc_selsup", dat = SelSup(), icon = None)
    plugins.RegisterCommandPlugin(id=MODULE_ID, str = "#$15v 1.10 - code.vonc.fr", info = 0, help = "code.vonc.fr", dat = SelSup(), icon = icone("selsup.png"))