[ Script ] decouper une polyligne aux points

braabu
Nouveau
24 Avril 2016
35
  • Auteur de la discussion
  • #1
bonjour !

je suis entrain de faire un script, et j'aurais besoin de decouper une polyligne suivant des points , je pensais y arriver en faisant ca :

Code:
sub main
Dim p as polyline
Dim a as Point2F
Dim polypoint As Point3F
    for each ent as Entity in view.SelectedEntities
    Dim plist As PointList = New PointList
    plist = PointListUtils.CreatePointlistFromPolyline(ent, 50)
'    CamBamUI.MainUI.ActiveView.CADFile.Add(plist)
    CamBamUI.MainUI.ActiveView.RefreshView()
    p  = ent
    Next ent


For Each it As PolylineItem In plist.Points
polypoint = it.Point
a = New Point2F(polypoint.x ,polypoint.y)
p.splitatpoint(a,0.4)
next

end sub
mais non .... ca marche pas
si l'un de vous peut me donner un coup de main :wink:

merci d'avance !
 
braabu
Nouveau
24 Avril 2016
35
  • Auteur de la discussion
  • #2
je v détailler un peu plus le but du code.
avec la creation d'une liste de point sur un polyligne, il, arrive que l'on "rate certain point important, comme un angle droit ou autre.
je compte donc faire un fonction qui va me creer une liste de n point avec en plus les point important si il y a.

dans le processus
création d'une liste de point,
découpe de la polyligne
je regarde si il y a des angles importants dans chaque segment.
je rajoute ces points.

mais il y a peut être plus simple.
ce qui me pose problème et qui m'a fait arrivé a cette facon de faire, ce n'est pas la détection des points important, mais le fait de les écrire au bon endroit dans la liste de points.
 
dh42
Compagnon
4 Septembre 2009
5 246
Près de St Etienne (42)
Salut,

plusieurs pb.

dans ta boucle (la 1iere) tu dimensionne la variable plist à chaque passage ; pas bon ; il faut la créer une seule fois, ensuite pour ne pas te retrouver avec des objets qui auront tous le même "pointeur", utilise plist.clone pour ajouter un clone de la liste de point dans le document.

dans la 2ieme boucle ; polylineitem n'est pas un membre de pointlist (mais de Polyline)

par contre, dans la 2ieme boucle, il y a un truc qui ne vas pas aller, car dans la 1iere tu assigne le pointeur de polyligne à p, mais si tu a plusieurs polylignes à traiter, p ne contiendra le pointeur que vers la dernière polyligne traité dans la 1iere boucle. Il faudrait soit stocker les p dans un tableau, soit faire le traitement de la 2ieme boucle juste avant de sortir de la 1iere et donc avant de changer de p.

Code:
sub main
Dim p as polyline
Dim a as Point2F
Dim plist As PointList
      
    for each ent as Entity in view.SelectedEntities
  
        plist = PointListUtils.CreatePointlistFromPolyline(ent, 50)
        CamBamUI.MainUI.ActiveView.CADFile.Add(plist.clone) 'ajoute une copie de plist dans le document
        CamBamUI.MainUI.ActiveView.RefreshView()
        p  = ent
    Next ent

    For Each it As point3f In plist.Points
        a = New Point2F(it.x ,it.y)
        p.splitatpoint(a,0.4)
    next

end sub
++
David
 
Dernière édition:
dh42
Compagnon
4 Septembre 2009
5 246
Près de St Etienne (42)
Re

Quelques info supplémentaires:

Dim plist As PointList = New PointList

Il n'est pas nécessaire, dans ce cas, de mettre le "= New PointList" car tout ce dont tu a besoin c'est d'un pointeur (plist) qui pointe sur une liste de points, et il n'est pas nécessaire de la créer car elle sera créée par le fonction "PointListUtils.CreatePointlistFromPolyline(), qui renvoi un pointeur (une adresse mémoire) dans plist.

le "= New PointList" réserve de la place en mémoire pour une liste de points, et renvoie l'adresse mémoire (un pointeur) du 1ier élément de la zone mémoire qui a été réservée par le "= New PointList" dans le variable plist.

Ce ne serait donc nécessaire que si tu voulais créer toi même une liste de points et y ajouter des données, mais ici c'est la fonction CreatePointlistFromPolyline() qui crée la liste et la remplis, puis passe l'adresse mémoire à la variable plist.

l'erreur "Ligne = 14 - Le nom 'plist' n'est pas déclaré." est dut au fait que tu déclare ta variable plist dans ta boucle for/each ; sa "portée" (sa validité) est limité à la boucle ; dès que tu sort de la boucle la variable n'est plus connue du programme et lorsque tu tente de l'utiliser ligne 14, le programme ne la connais plus.

si une variable est déclarée dans une boucle, elle n'est valable que dans la boucle ; si elle est déclarée dans une sub ou une fonction, elle n'est valable que dans la sub ou la fonction ou elle a été déclarée, pour avoir une variable connue de toutes les fonctions/sub (globale), il faut la déclarer en dehors de la sub.

exemple d'une variable globale connue à la fois dans main() et dans affiche()

Code:
Dim a As long
sub main
   a = 10
   affiche()
end sub

sub affiche
    app.log(a)
end sub
même chose si tu écris:

Code:
sub main

for n as long = 0 to 100
   ' .......
next n

app.log(n)

end sub
la variable n ne sera connue que dans la boucle for/next, et app.log(n) renverra une erreur "le nom 'n' n'est pas déclaré"

par contre, si tu écris:

Code:
sub main

Dim n as long
for n = 0 to 100
    '.......
next n

app.log(n)

end sub
n sera bien connu en dehors de la boucle for/next.

mais il y a peut être plus simple.
ce qui me pose problème et qui m'a fait arrivé a cette facon de faire, ce n'est pas la détection des points important, mais le fait de les écrire au bon endroit dans la liste de points.
Si tu n'y arrive pas, j'ai trouvé une méthode qui fonctionne "en direct" sur l'interface, il suffira de faire la même chose par programmation.

- obtenir la longueur de la polyligne (Polyline.GetPerimeter) et la diviser par le nb de points voulus pour obtenir l'espacement entre les points.
- décomposer la polyligne en ses divers arcs/ligne (Polyline.ToPrimitives) on obtiens des entity
- convertir les arcs/lignes (entity) obtenus en polylignes (Arc.ToPolyline , Line.ToPolyline )
- pour chaque polyligne, utiliser dessiner/points/contour géométrie par pas avec la valeur d'espacement obtenue au début. (CreatePointlistFromPolylineStep ())

cela te crée des points à intervalle régulier, mais surtout, chaque segment à un point à son début, et comme le début d'un segment c'est la fin du précédant, tu a tout tes points "important" correspondant aux points internes de la polyligne. cas particulier, si la polyligne est ouverte, il faudra ajouter le dernier point ; si elle est fermée, le dernier est aussi le premier donc il y est déjà.

tu te retrouve donc avec une série de listes de points qu'il suffit de joindre pour obtenir les points dans le bon ordre.
il y a une fonction JoinPointlist dans le pointlistutil, mais les listes de points doivent avoir été ajoutées au document, mais tu peux aussi le faire avec une méthode pointlist.add() en remplissant une liste vierge avec les valeurs contenues dans les pointlist obtenues avec CreatePointlistFromPolylineStep()

++
David
 
Dernière édition:
La dernière réponse à ce sujet date de plus de 6 mois
Haut