bazoul Posté(e) le 14 avril 2011 Posté(e) le 14 avril 2011 Bonjours,Alors voila j'ai un petit soucis que je n'ai toujours pas réussi a résoudre,j'explique : J'ai en entré N polyligne fermée.Ces polylignes s'intersectent.Ce que je voudrais,c'est un algo qui a partir de deux polylignes en entré retourne une seule polyligne en sortie.Le must serait de ne travailler qu'avec un nuage de point,mais malgrès mes recherches et l'élaboration d'un algo basé sur Graham'scan je ne suis pas parvenue a grand chose ... Au jour d'aujourd'hui,je me débrouille comme je peux en passant par des régions et des opérations booléeennes, mais ce n'est pas le top.Des problèmes peuvent survenir à la suite de bug autocad ( exemple;après l'union de deux régions autocad peux nous sortir une région résultante qui n'est pas planaire!! ) et qui rendent la fonction explode non fonctionnelle.Du moment où cette région résultante n'est plus planaire,toutes les opérations booléenne derrière donneront une région résultante pourrie. Dans la continuité de la problématique précédente ( un algo qui me donnerait le meme résultat qu'avec les régions ) j'ai un autre problème mais cette fois ci avec des hachure : Grosso,l'utilisateur dessine une polyligne dans laquelle vont se trouver des parcelles ( polyligne ).Une fois que l'utilisateur a terminé le tracé de la polyligne,je récupère le contenu et hachure la zone.Puis via une petite interface il peux décocher les zones a ne pas hachurer ... là ou je coince,c'est lorsque la hachure a créer possède deux boucles externe on va dire ... en fonction de la géométrie,autocad me rajoute des points a mon contour,et je me retrouve avec des segments de longueur 0 .... derrière la hachure merde et ne prends pas en compte le contour incriminé. Pour terminerai par,merci à ceux qui vont prendre le temps de lire mon pavé,je bosse en VB.NET sur autocad 2009 et que je suis ouvert a répondre a toutes questions. Cordialement, PS: image explicative du premier problèmehttp://www.hebergeur-images.fr/images/1250423745.jpg [Edité le 15/4/2011 par bazoul]
(gile) Posté(e) le 14 avril 2011 Posté(e) le 14 avril 2011 Salut, Je ne suis pas sûr de comprendre la demande (je ne vois pas l'image) mais s'il s'agit de faire une "enveloppe convexe" (convex hull) à partir d'un nuage de points (Graham's scan), je te propose ces codes : EDIT : ajout d'un facteur de tolérance dans la comparaison des cosinus lors du tri de la liste (problème avec les points colinéaires dans certains cas) C# using System.Collections.Generic; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.Runtime; using AcAp = Autodesk.AutoCAD.ApplicationServices.Application; namespace ConvexHull { public class Commands { private Point2d _p0; private bool Clockwise(Point2d p1, Point2d p2, Point2d p3) { return ((p2.X - p1.X) * (p3.Y - p1.Y) - (p2.Y - p1.Y) * (p3.X - p1.X)) < 1e-9; } private int ComparePoints(Point2d p1, Point2d p2) { if (p1.IsEqualTo(p2)) return 0; double d1 = _p0.GetDistanceTo(p1); double d2 = _p0.GetDistanceTo(p2); if (d1 == 0.0) return -1; if (d2 == 0.0) return 1; double cos = (p2.X - _p0.X) / d2 - (p1.X - _p0.X) / d1; if (cos < -1e-9) return -1; if (cos > 1e-9) return 1; return d1.CompareTo(d2); } private List<Point2d> ConvexHull(List<Point2d> pts) { _p0 = pts[0]; for (int i = 1; i < pts.Count; i++) { Point2d pt = pts[i]; if (pt.Y < _p0.Y || (pt.Y == _p0.Y && pt.X < _p0.X)) _p0 = pt; } pts.Remove(_p0); pts.Sort(ComparePoints); pts.Insert(0, _p0); for (int i = 1; i < pts.Count - 1; i++) { while (i > 0 && Clockwise(pts[i - 1], pts[i], pts[i + 1])) { pts.RemoveAt(i); i--; } } return pts; } [CommandMethod("ch", CommandFlags.UsePickSet)] public void testCh() { Document doc = AcAp.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; TypedValue[] filter = new TypedValue[1] { new TypedValue(0, "POINT") }; PromptSelectionResult psr = ed.GetSelection(new SelectionFilter(filter)); if (psr.Status != PromptStatus.OK) return; using (Transaction tr = db.TransactionManager.StartTransaction()) using (Polyline pline = new Polyline()) { List<Point2d> pts = new List<Point2d>(); foreach (SelectedObject so in psr.Value) { DBPoint dbPt = (DBPoint)tr.GetObject(so.ObjectId, OpenMode.ForRead); pts.Add(new Point2d(dbPt.Position.X, dbPt.Position.Y)); } for (int i = 0; i < ConvexHull(pts).Count; i++) { pline.AddVertexAt(i, pts[i], 0.0, 0.0, 0.0); } pline.Closed = true; pline.SetDatabaseDefaults(); BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite); btr.AppendEntity(pline); tr.AddNewlyCreatedDBObject(pline, true); tr.Commit(); } } } } ou F# module ConvexHull open Autodesk.AutoCAD.ApplicationServices open Autodesk.AutoCAD.DatabaseServices open Autodesk.AutoCAD.EditorInput open Autodesk.AutoCAD.Geometry open Autodesk.AutoCAD.Runtime type AcAp = Autodesk.AutoCAD.ApplicationServices.Application let clockwise (p1:Point2d) (p2:Point2d) (p3:Point2d) = (p2.X - p1.X) * (p3.Y - p1.Y) - (p2.Y - p1.Y) * (p3.X - p1.X) < 1e-8 let convexHull (pts : Point2d seq) = let rec fill acc pt = match acc with | a :: b :: _ when clockwise b a pt -> fill acc.Tail pt | _ -> pt :: acc let p0 = pts |> Seq.reduce (fun p1 p2 -> if p2.Y < p1.Y || (p1.Y = p2.Y && p2.X < p1.X) then p2 else p1) pts |> List.ofSeq |> List.sortBy (fun p -> let d = p0.GetDistanceTo(p) (Math.Round((p0.X - p.X) / d, 8), d)) |> List.fold fill [] |> List.rev [<CommandMethod("ch")>] let Test() = let doc = AcAp.DocumentManager.MdiActiveDocument let db = doc.Database let ed = doc.Editor let psr = ed.GetSelection(new SelectionFilter([| new TypedValue(0, "POINT") |])) if psr.Status = PromptStatus.OK then use tr = db.TransactionManager.StartTransaction() use pl = new Polyline() psr.Value |> Seq.cast<_> |> Seq.map (fun (so : SelectedObject) -> let pt = tr.GetObject(so.ObjectId, OpenMode.ForRead) :?> DBPoint new Point2d(pt.Position.X, pt.Position.Y)) |> convexHull |> List.fold(fun i p -> pl.AddVertexAt(i, p, 0.0, 0.0, 0.0); i + 1) 0 |> ignore pl.Closed <- true pl.SetDatabaseDefaults() let btr = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) :?> BlockTableRecord btr.AppendEntity(pl) |> ignore tr.AddNewlyCreatedDBObject(pl, true) tr.Commit() Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
bazoul Posté(e) le 15 avril 2011 Auteur Posté(e) le 15 avril 2011 Je te remercie giles pour ce code,ça ne réponds pas a mon besoin mais je te remercie de la peine que tu t'es donné. J'étais a l'origine partie de graham'scan pour obtenir l'enveloppe convexe.Puis de cette enveloppe convexe j'intégré une partie des points du contour des polyligne de départ au contour final.Cela fonctionnait pas mal,mais j'étais bloqué au moment ou il fallait trouver le meilleure point de raccord diront nous entre les deux polylignes de départ ... En fait,mon besoin c'est un algorythme de calcul d'enveloppe concave,et non convexe ... et les concavité,c'est la que ça coince ! PS: je vois que tu tattes un peu le F#,quel est l'interet de faire du F# plutot que du vb.net ( que je pratique ,ou encore du C# que j'aimerais bien pratiquer mais que je n'ai pas le temps de le faire sur mon lieux de travail! ) PPS: d'ailleurs en regardant un peu la syntaxe du F# j'ai l'impression de voir un peu du vba notament avec les 'let' qui je pense était les 'set' en vba pour affectuer une variable de type objet ... [Edité le 15/4/2011 par bazoul]
(gile) Posté(e) le 15 avril 2011 Posté(e) le 15 avril 2011 Salut, quel est l'interet de faire du F# Par rapport à VB. ou C# (qui sont semblables), F# apporte, en plus, la possibilité de faire de la programmation fonctionnelle (en ça F# est beaucoup plus proche du LISP que du VBA) et des bibliothèques spécifiques, voir ici. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
(gile) Posté(e) le 16 avril 2011 Posté(e) le 16 avril 2011 Re, Pour ton problème, j'avais fait un truc en LISP (Fusion sur cette page) mais qui utilise les régions (d'ailleurs, je n'ai jamais eu de soucis avec ni eu de retour négatif). Si tu ne veux pas passer par les régions, une façon serait de : - calculer l'aire algébrique des polylignes, si elle est négative, en inverse le sens pour avoir toutes les polylignes dans le même sens - trouver les points d'intersection des polylignes - à partir du premier sommet d'une polyligne récupérer tous les sommets jusqu'à une intersection et continuer à partir du paramètre à ce point d'intersection sur l'autre polyligne jusqu'au prochain point d'intersection où on change à nouveau de polyligne... Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
bazoul Posté(e) le 18 avril 2011 Auteur Posté(e) le 18 avril 2011 Oui giles,j'étais parti sur cette solution au départ.Sa marche niquel du moment que tu n'a pas de boucle interne. A partir du moment ou ya une boucle interne sa se complique.Ou alors a partir du moment ou les deux contour de polyligne se coupent en formant du coup des contour indépendant ...Vaste problème que celui de la création de région.J'ai cherché un algorythme permettant de me dégager des régions pour bosser directement avec des points,sans succès réel ( a savoir,sa ne marche que dans les cas simple! ) Concernant mes soucis de région,je suis sur autocad 2009,le problème en question a peut etre été corrigé dans les versions ultérieures ... mais je peux te garantir qu'en créant une région avec une liste de point2D,on peut obtenir des régions bizaroides ...
(gile) Posté(e) le 18 avril 2011 Posté(e) le 18 avril 2011 mais je peux te garantir qu'en créant une région avec une liste de point2D,on peut obtenir des régions bizaroides ... Pourquoi utiliser des points, la méthode statique (shared en VB) Region.CreateFromCurves permet de créer une région à partir d'une collection de lignes et arcs. J'ai essayer de transposer ce que j'avais écrit en LISP en C#, ça semble marcher (les polylignes sélectionnées doivent être dans le même plan même s'il est différent du plan du SCG). http://gile.pagesperso-orange.fr/MergePlines.gif using System; using System.Collections.Generic; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.Runtime; using AcAp = Autodesk.AutoCAD.ApplicationServices.Application; namespace MergePlines { public class Commands { Point2d _pt; Document _doc = AcAp.DocumentManager.MdiActiveDocument; private bool PointPredicate(Point2d p) { return _pt.IsEqualTo(p); } private void Dispose(DBObjectCollection col) { for (int i = 0; i < col.Count; i++) { col[i].Dispose(); } } private void MergePlines(ObjectId[] ids) { Database db = _doc.Database; using (Transaction tr = db.TransactionManager.StartTransaction()) { DBObjectCollection segments = new DBObjectCollection(); BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite); Polyline pl = (Polyline)tr.GetObject(ids[0], OpenMode.ForWrite); Vector3d normal = pl.Normal; double elev = pl.Elevation; pl.Explode(segments); pl.Erase(); Plane plane = new Plane(Point3d.Origin, normal); for (int i = 1; i < ids.Length; i++) { pl = (Polyline)tr.GetObject(ids[i], OpenMode.ForWrite); if (pl.Elevation == elev && pl.Normal.IsEqualTo(normal)) { pl.Explode(segments); pl.Erase(); } } DBObjectCollection regions = Region.CreateFromCurves(segments); Region reg = (Region)regions[0]; for (int i = 1; i < regions.Count; i++) { reg.BooleanOperation(BooleanOperationType.BoolUnite, (Region)regions[i]); regions[i].Dispose(); } segments.Clear(); Dispose(segments); reg.Explode(segments); reg.Dispose(); List<Point2d> starts = new List<Point2d>(); List<Point2d> ends = new List<Point2d>(); List<double> bulges = new List<double>(); for (int i = 0; i < segments.Count; i++) { if (segments[i] is Region) { ((Region)segments[i]).Explode(segments); continue; } Curve crv = (Curve)segments[i]; Point3d start = crv.StartPoint; Point3d end = crv.EndPoint; double bulge = 0.0; if (crv is Arc) { Arc arc = (Arc)crv; double angle = arc.Center.GetVectorTo(start).GetAngleTo(arc.Center.GetVectorTo(end), arc.Normal); bulge = Math.Tan(angle / 4.0); } starts.Add(start.Convert2d(plane)); ends.Add(end.Convert2d(plane)); bulges.Add(bulge); } Dispose(segments); while (starts.Count > 0) { using (Polyline pline = new Polyline()) { pline.AddVertexAt(0, starts[0], bulges[0], 0.0, 0.0); pline.AddVertexAt(1, ends[0], 0.0, 0.0, 0.0); _pt = ends[0]; starts.RemoveAt(0); ends.RemoveAt(0); bulges.RemoveAt(0); int i = 2; while (starts.Contains(_pt) || ends.Contains(_pt)) { int index = starts.FindIndex(PointPredicate); if (index > -1) { _pt = ends[index]; pline.AddVertexAt(i, _pt, 0.0, 0.0, 0.0); pline.SetBulgeAt(i - 1, bulges[index]); } else { index = ends.FindIndex(PointPredicate); _pt = starts[index]; pline.AddVertexAt(i, _pt, 0.0, 0.0, 0.0); pline.SetBulgeAt(i - 1, -bulges[index]); } starts.RemoveAt(index); ends.RemoveAt(index); bulges.RemoveAt(index); i++; } pline.RemoveVertexAt(pline.NumberOfVertices - 1); pline.SetDatabaseDefaults(); pline.Closed = true; pline.Normal = normal; pline.Elevation = elev; btr.AppendEntity(pline); tr.AddNewlyCreatedDBObject(pline, true); } } tr.Commit(); } } [CommandMethod("Test")] public void Test() { Editor ed = _doc.Editor; TypedValue[] filter = new TypedValue[3]{ new TypedValue(0, "LWPOLYLINE"), new TypedValue(-4, "&"), new TypedValue(70, 1)}; PromptSelectionResult psr = ed.GetSelection(new SelectionFilter(filter)); if (psr.Status == PromptStatus.OK) { try { MergePlines(psr.Value.GetObjectIds()); } catch (Autodesk.AutoCAD.Runtime.Exception e) { ed.WriteMessage("\nErreur: " + e.Message); } } } } } Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
bazoul Posté(e) le 19 avril 2011 Auteur Posté(e) le 19 avril 2011 Je vais tester ton approche ..en revanche,pour l'explosion de la région je te conseillerai plutot le code suivant ( désolé je ne suis pas expert C#,ce sera du vb ... ) Dim sbep As SubentityId Dim ids As ObjectId() Dim OutsidePath As FullSubentityPath Dim lenti As Entity Dim CurrentRegion As Region Dim comptent As Integer = 1 Dim EntitiesInRegionToConvert As New DBObjectCollection Dim EntitiesFromExplodeRegion As New DBObjectCollection 'On commence a 1 sinon on obtient systématiquement Nothing a la position 0 While True Try ids = New ObjectId(0) {} 'indiquer le type de l'entité que l'on souhaite récupérer sbep = New SubentityId(SubentityType.Face, comptent) OutsidePath = New FullSubentityPath(ids, sbep) 'Récupérer l'entité au conpteur indiquer lenti = RegionToConvert.GetSubentity(OutsidePath) 'si on obtient Nothing c'est qu'on a plus rien a récupérer,donc on sort du while pour reprendre le cours 'normal du traitement If lenti Is Nothing Then Exit While EntitiesInRegionToConvert.Add(lenti) Catch tr.Dispose() : tr = Nothing Return False End Try comptent += 1 End While For i As Integer = 0 To EntitiesInRegionToConvert.Count - 1 System.Windows.Forms.Application.DoEvents() 'Récupétation de la région courante CurrentRegion = CType(EntitiesInRegionToConvert.Item(i), Region) While True Try ids = New ObjectId(0) {} 'indiquer le type de l'entité que l'on souhaite récupérer sbep = New SubentityId(SubentityType.Edge, comptent) OutsidePath = New FullSubentityPath(ids, sbep) 'Récupérer l'entité au conpteur indiquer lenti = CurrentRegion.GetSubentity(OutsidePath) 'si on obtient Nothing c'est qu'on a plus rien a récupérer,donc on sort du while pour reprendre le cours 'normal du traitement If lenti Is Nothing Then Exit While EntitiesFromExplodeRegion.Add(lenti) Catch tr.Dispose() : tr = Nothing Return False End Try comptent += 1 End While CurrentRegion.Dispose() : CurrentRegion = Nothing Next i EntitiesInRegionToConvert.Dispose() : EntitiesInRegionToConvert = Nothing Code testé et fonctionnel là ou d'autre pouvais produire des erreurs notament sur autocad 2009 ...
(gile) Posté(e) le 19 avril 2011 Posté(e) le 19 avril 2011 Merci pour la recommandation, mais je ne rencontre aucun problème avec Entity.Explode() (testé sur A2007, A2010 et A2011). J'en ai profité pour finaliser un commande qui fonctionne que que soient les plans de construction de polylignes sélectionnées. http://www.theswamp.org/index.php?topic=37976.msg429899#msg429899 La DLL : MergePlines.zip Le code : using System; using System.Collections.Generic; using System.Globalization; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.Runtime; using AcAp = Autodesk.AutoCAD.ApplicationServices.Application; namespace MergePlines { public class Commands { bool _en; Point2d _pt; Document _doc; public Commands() { //System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US"); //System.Threading.Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US"); _en = CultureInfo.CurrentCulture.Name.StartsWith("en-"); _doc = AcAp.DocumentManager.MdiActiveDocument; } private bool PointPredicate(Point2d p) { return _pt.IsEqualTo(p); } private void DisposeAll(DBObjectCollection col) { for (int i = 0; i < col.Count; i++) { col[i].Dispose(); } } private int MergePlines(ObjectIdCollection ids, bool erase) { Database db = _doc.Database; int result = 0; using (Transaction tr = db.TransactionManager.StartTransaction()) using (DBObjectCollection segments = new DBObjectCollection()) { BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite); List<Point2d> starts = new List<Point2d>(); List<Point2d> ends = new List<Point2d>(); List<double> bulges = new List<double>(); List<Polyline> plines = new List<Polyline>(); Polyline pl; while (ids.Count > 0) { segments.Clear(); starts.Clear(); ends.Clear(); bulges.Clear(); plines.Clear(); pl = (Polyline)tr.GetObject(ids[0], OpenMode.ForWrite); Vector3d normal = pl.Normal; double elev = pl.Elevation; Plane plane = new Plane(Point3d.Origin, normal); plines.Add(pl); ids.RemoveAt(0); for (int i = 0; i < ids.Count; ) { pl = (Polyline)tr.GetObject(ids[i], OpenMode.ForWrite); if (Math.Abs(pl.Elevation - elev) < 1e-12 && pl.Normal.IsEqualTo(normal)) { plines.Add(pl); ids.RemoveAt(i); } else i++; } if (plines.Count < 2) continue; for (int i = 0; i < plines.Count; i++) { pl = plines[i]; pl.Explode(segments); if (erase) pl.Erase(); } using (DBObjectCollection regions = Region.CreateFromCurves(segments)) { Region reg = (Region)regions[0]; for (int i = 1; i < regions.Count; i++) { reg.BooleanOperation(BooleanOperationType.BoolUnite, (Region)regions[i]); regions[i].Dispose(); } DisposeAll(segments); segments.Clear(); reg.Explode(segments); reg.Dispose(); for (int i = 0; i < segments.Count; i++) { if (segments[i] is Region) { ((Region)segments[i]).Explode(segments); continue; } Curve crv = (Curve)segments[i]; Point3d start = crv.StartPoint; Point3d end = crv.EndPoint; double bulge = 0.0; if (crv is Arc) { Arc arc = (Arc)crv; double angle = arc.Center.GetVectorTo(start).GetAngleTo(arc.Center.GetVectorTo(end), arc.Normal); bulge = Math.Tan(angle / 4.0); } starts.Add(start.Convert2d(plane)); ends.Add(end.Convert2d(plane)); bulges.Add(bulge); } DisposeAll(segments); while (starts.Count > 0) { using (Polyline pline = new Polyline()) { pline.AddVertexAt(0, starts[0], bulges[0], 0.0, 0.0); pline.AddVertexAt(1, ends[0], 0.0, 0.0, 0.0); _pt = ends[0]; starts.RemoveAt(0); ends.RemoveAt(0); bulges.RemoveAt(0); int i = 2; while (starts.Contains(_pt) || ends.Contains(_pt)) { int index = starts.FindIndex(PointPredicate); if (index > -1) { _pt = ends[index]; pline.AddVertexAt(i, _pt, 0.0, 0.0, 0.0); pline.SetBulgeAt(i - 1, bulges[index]); } else { index = ends.FindIndex(PointPredicate); _pt = starts[index]; pline.AddVertexAt(i, _pt, 0.0, 0.0, 0.0); pline.SetBulgeAt(i - 1, -bulges[index]); } starts.RemoveAt(index); ends.RemoveAt(index); bulges.RemoveAt(index); i++; } pline.RemoveVertexAt(pline.NumberOfVertices - 1); pline.SetDatabaseDefaults(); pline.Closed = true; pline.Normal = normal; pline.Elevation = elev; btr.AppendEntity(pline); tr.AddNewlyCreatedDBObject(pline, true); result++; } } } } tr.Commit(); } return result; } [CommandMethod("UPL", CommandFlags.UsePickSet)] public void UnionPlines() { Editor ed = _doc.Editor; TypedValue[] filter = new TypedValue[3]{ new TypedValue(0, "LWPOLYLINE"), new TypedValue(-4, "&"), new TypedValue(70, 1)}; PromptSelectionResult psr = ed.GetSelection(new SelectionFilter(filter)); if (psr.Status != PromptStatus.OK) return; PromptKeywordOptions pko = new PromptKeywordOptions("\nEffacer les polylignes source ?: "); if (_en) { pko.Message = "\nErase source polylines ?: "; pko.Keywords.Add("Yes"); pko.Keywords.Add("No"); pko.Keywords.Default = "Yes"; } else { pko.Keywords.Add("Oui"); pko.Keywords.Add("Non"); pko.Keywords.Default = "Oui"; } pko.AllowNone = true; PromptResult pr = ed.GetKeywords(pko); if (pr.Status == PromptStatus.Cancel) return; bool erase = _en ? pr.StringResult == "Yes" : pr.StringResult == "Oui"; try { ObjectIdCollection ids = new ObjectIdCollection(psr.Value.GetObjectIds()); int n = MergePlines(ids, erase); if (_en) ed.WriteMessage("\n{0} polyline{1} have been created", n, n > 1 ? "s" : ""); else ed.WriteMessage("\n{0} polyligne{1} créée{1}", n, n > 1 ? "s" : ""); } catch (Autodesk.AutoCAD.Runtime.Exception e) { ed.WriteMessage("\n{0}: {1}", _en ? "Error" : "Erreur", e.Message); } } } } Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
lecrabe Posté(e) le 19 avril 2011 Posté(e) le 19 avril 2011 Hello Gilles Super ta nouvelle routine de fusion des polylignes - Merci ! :) Je viens de la tester sur MAP 2008 et 2010 32 bits Sauf que il faudrait peut etre redire que :- Chargement de ta super DLL par NETLOAD- Lancement par UPL (pour Union PLines) J'ai un test encore plus complique que le tien et dans une 2eme etape j'en fais un joli MPOLYGON :cool: Encore Merci, Le Decapode Autodesk Expert Elite Team
(gile) Posté(e) le 20 avril 2011 Posté(e) le 20 avril 2011 J'ai mis à jour le LISP Fusion sur cette page, pour qu'il ait le même comportement. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
lecrabe Posté(e) le 20 avril 2011 Posté(e) le 20 avril 2011 Hello Gilles Eh c quoi alors les avantages / inconvenient de ces 2 routines !? UPL (Mergeplines) est-il plus rapide ? Et sinon une autre question : la fiabilite de 2 methodes !? Le Decapode (Unioniste de PolyLignes) Autodesk Expert Elite Team
(gile) Posté(e) le 20 avril 2011 Posté(e) le 20 avril 2011 Eh c quoi alors les avantages / inconvenient de ces 2 routines !? Elles font la même choses, donc les avantages/inconvénients sont ceux de LISP par rapport à .NET : LISP est plus facile à charger, maintenir, modifier, .NET est (peut-être, voir ci-dessous) un peu plus rapide à l'exécution.C'est ce sujet qui m'a amené à traduire en .NET le LISP Fusion. En transcrivant le code je l'ai amélioré (pour qu'il traite les polylignes coplanaires par groupe), j'ai ensuite ajouté cette amélioration aux (vieux) LISP Fusion. UPL (Mergeplines) est-il plus rapide ? Théoriquement les programmes .NET (compilés) s'exécutent plus vite que les programmes LISP (interprétés). Sans avoir testé, je pense que dans ce cas, la différence devrait être relativement insensible, le processus le plus "couteux" étant la création de regions qui, dans les deux cas utilise le modeleur. La différence pourrait se faire sur les tris des polylignes et les différentes boucles et ne serait donc notable qu'avec de grandes quantité de polylignes à traiter. Et sinon une autre question : la fiabilite de 2 methodes !? Difficile à dire pour l'instant, c'est tout neuf et demanderait plus de test, mais il ne devrait pas y avoir de différence de fiabilité entre les deux méthode. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
fabcad Posté(e) le 21 avril 2011 Posté(e) le 21 avril 2011 Bonjour Gile,J'ai téléchargé MergePlines et PolylineEdit_English (PolylineEdit.dll) la fonction netload les charge bien mais pour une j'ai essayé UPL mais la ligne de commande reste à Commande inconnue et pareil pour l'autre j'ai essayé tous les noms possibles mais pas de lancement de MergePlines et de PolylineEdit. Le tout sur AutoCAD MAP 3D 2009. Cordialement, Fabcad
(gile) Posté(e) le 21 avril 2011 Posté(e) le 21 avril 2011 Salut, Pour MergePlines.zip, j'ai effectivement cafouillé, j'avais renommé la commande pour faire des test comparatifs*.Le nouveau lien pointe bien sur la bonne DLL avec la commande nommée : UPLPour PolylineEdit, si tu as bien téléchargé le ZIP depuis ce sujet, les commandes sont : AVX et DVX. * J'ai finalement fait quelques test de vélocité les versions .NET (C# ou F#) sont environ 2.5 fois plus rapides que la version LISP (Fusion). Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
fabcad Posté(e) le 21 avril 2011 Posté(e) le 21 avril 2011 Merci Gile pour les informations, c'est génial comme d'habitude. Pour info : PlineEdit.dll fonctionne à merveille et en plus cerise sur le gâteau, elle conserve les données d'objets. Encore merci. A+ [Edité le 22/4/2011 par fabcad]
Messages recommandés
Créer un compte ou se connecter pour commenter
Vous devez être membre afin de pouvoir déposer un commentaire
Créer un compte
Créez un compte sur notre communauté. C’est facile !
Créer un nouveau compteSe connecter
Vous avez déjà un compte ? Connectez-vous ici.
Connectez-vous maintenant