bonuscad Posté(e) le 23 avril 2007 Partager Posté(e) le 23 avril 2007 C'est une routine que j'essaye d'améliorer, j'ai voulu l'écrire sans faire d'appel à commande.Il me reste juste un petit problème à résoudre, c'est le côté de décalage pour les arcs. Pour les segments droit ça fonctionne bien, mais pour les arrondis je ne sais comment faire pour avoir une fiabilité sur la détermination du côté à décaler.Un autre problème (moins important); je ne sais comment émuler le paramètre "par" ("_through") de la commande décaler avec (vla-Offset). La routine s'appuie sur (near_vertex) sur laquelle (gile) m'a déjà bien aidé. (defun c:offset_vertex ( / obj dxf_obj obj_vlax pt_sel par i pt_first pt_snd bulge e_next pt_ref lst_dxf rad p_cen dxf_210 dis_offset where_pt v1 v2 det_or) (while (not (setq obj (entsel "\nChoix d'une polyligne ")))) (cond ((or (eq (cdr (assoc 0 (setq dxf_obj (entget (car obj))))) "LWPOLYLINE") (and (eq (cdr (assoc 0 dxf_obj)) "POLYLINE") (zerop (boole 1 112 (cdr (assoc 70 dxf_obj)))) ) ) (vl-load-com) (setq obj_vlax (vlax-ename->vla-object (car obj)) pt_sel (vlax-curve-getClosestPointToProjection obj_vlax (trans (cadr obj) 1 0) (mapcar '- (trans (getvar "VIEWDIR") 1 0) (trans '(0 0 0) 1 0)) ) par (vlax-curve-getParamAtPoint obj_vlax pt_sel) i 0 ) (if (>= par (vlax-curve-getEndParam obj_vlax)) (setq par (1- par))) (setq pt_first (trans (vlax-curve-getPointAtParam obj_vlax (fix par)) 0 1) ) (if (= (1+ (fix par)) (vlax-curve-getEndParam obj_vlax)) (setq pt_snd (trans (vlax-curve-getEndPoint obj_vlax) 0 1)) (setq pt_snd (trans (vlax-curve-getPointAtParam obj_vlax (1+ (fix par))) 0 1)) ) (cond ((eq (cdr (assoc 0 dxf_obj)) "LWPOLYLINE") (while (or (/= (caar dxf_obj) 42) (if (< i (fix par)) (setq i (1+ i)))) (setq bulge (cdadr dxf_obj) dxf_obj (cdr dxf_obj)) ) ) (T (setq e_next (entnext (cdar dxf_obj))) (repeat (fix par) (setq e_next (entnext e_next))) (setq bulge (cdr (assoc 42 (entget e_next)))) ) ) (setq dxf_obj (entget (car obj)) pt_ref pt_snd) (if (zerop bulge) (setq lst_dxf (list (cons 0 "LINE") (cons 100 "AcDbEntity") (assoc 67 dxf_obj) (assoc 410 dxf_obj) (cons 8 (getvar "CLAYER")) (cons 100 "AcDbLine") (cons 10 (trans pt_first 1 0)) (cons 11 (trans pt_snd 1 0)) (assoc 210 dxf_obj) ) ) (setq dxf_210 (cdr (assoc 210 dxf_obj)) pt_first (trans pt_first 1 dxf_210) pt_snd (trans pt_snd 1 dxf_210) rad (abs (/ (distance pt_first pt_snd) (sin (* 2.0 (atan bulge))) 2.0)) p_cen (polar pt_first (if (> bulge 0.0) (+ (angle pt_first pt_snd) (- (/ pi 2.0) (* 2.0 (atan bulge)))) (- (angle pt_first pt_snd) (+ (/ pi 2.0) (* 2.0 (atan bulge)))) ) rad ) lst_dxf (list (cons 0 "ARC") (cons 100 "AcDbEntity") (assoc 67 dxf_obj) (assoc 410 dxf_obj) (cons 8 (getvar "CLAYER")) (cons 100 "AcDbCircle") (cons 10 p_cen) (cons 40 rad) (cons 100 "AcDbArc") (cons 50 (angle p_cen (if (> bulge 0.0) pt_first pt_snd))) (cons 51 (angle p_cen (if (> bulge 0.0) pt_snd pt_first))) (assoc 210 dxf_obj) ) ) ) (foreach n '(6 39 48 62 370 420) (if (assoc n dxf_obj) (setq lst_dxf (append lst_dxf (list (assoc n dxf_obj)))) ) ) (initget "Par _Through") (setvar "OFFSETDIST" (if (not (setq dis_offset (getdist (strcat "\nSpécifiez la distance de décalage ou [Par] <" (if (< (getvar "OFFSETDIST") 0) "Par" (rtos (getvar "OFFSETDIST"))) ">: ")))) (progn (if (< (getvar "OFFSETDIST") 0) (setq dis_offset "Through")) (getvar "OFFSETDIST")) (if (eq dis_offset "Through") -1 dis_offset) ) ) (if (< (getvar "OFFSETDIST") 0) (princ "\nAttribuez une valeur à \"Par le point\": ") (princ "\nSpécifiez un point sur le côté à décaler: ") ) (initget 9) (setq where_pt (getpoint)) (entmake lst_dxf) (setq e_last (entlast)) (if (< (getvar "OFFSETDIST") 0) (setvar "OFFSETDIST" (distance (vlax-curve-getClosestPointToProjection e_last (trans where_pt 1 0) (mapcar '- (trans (getvar "VIEWDIR") 1 0) (trans '(0 0 0) 1 0)) T ) (list (car (trans where_pt 1 0)) (cadr (trans where_pt 1 0))) ) ) ) (if (eq "LINE" (cdr (assoc 0 lst_dxf))) (setq v1 (mapcar '- pt_ref pt_sel) v2 (mapcar '- (trans where_pt 1 0) pt_sel) ) (setq v1 (mapcar '- (polar pt_sel (+ (angle pt_sel (trans p_cen dxf_210 0)) (/ pi 2)) rad) pt_sel) v2 (mapcar '- (trans where_pt 1 0) pt_sel) ) ) (setq det_or (apply '(lambda (x1 y1 z1 x2 y2 z2) (- (* x1 y2) (* y1 x2))) (append v1 v2))) (cond ((> det_or 0.0) (setvar "OFFSETDIST" (abs (getvar "OFFSETDIST")))) ((< det_or 0.0) (setvar "OFFSETDIST" (- (abs (getvar "OFFSETDIST"))))) ) (if (vl-catch-all-error-p (vl-catch-all-apply 'vla-Offset (list (vlax-ename->vla-object e_last) (getvar "OFFSETDIST") ) ) ) (princ "\nL'objet ne peut pas être décalé.") (setvar "OFFSETDIST" (if (eq dis_offset "Through") -1 (abs (getvar "OFFSETDIST")))) ) (entdel e_last) ) (T (princ "\nN'est pas une polyligne valable pour cette fonction!") ) ) (prin1) ) [Edité le 24/4/2007 par bonuscad] Application de la gestion d'erreur de Gilles, plus élégante que la mienne. [Edité le 24/4/2007 par bonuscad] Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius Lien vers le commentaire Partager sur d’autres sites More sharing options...
(gile) Posté(e) le 23 avril 2007 Partager Posté(e) le 23 avril 2007 Salut, Et encore bravo, pour quelqu'un qui veut "passer la main"... ;) Pour déterminer le côté de décalage des arcs, je suggèrerais de faire un test différent de celui des segments rectilignes.Il suffirait de faire la différence entre : la distance entre le centre et le point retourné par grread et le rayon de l'arc. (if (= "LINE" (cdr (assoc 0 lst_dxf))) (setq v1 (mapcar '- pt_ref pt_sel) v2 (mapcar '- (trans (cadr key) 1 0) pt_sel) det_or (apply '(lambda (x1 y1 z1 x2 y2 z2) (- (* x1 y2) (* y1 x2))) (append v1 v2) ) ) (setq det_or (- (distance p_cen (trans (cadr key) 1 dxf_210)) rad)) ) Je n'ai pas testé en profondeur, mais ça semble fonctionner. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD Lien vers le commentaire Partager sur d’autres sites More sharing options...
bonuscad Posté(e) le 24 avril 2007 Auteur Partager Posté(e) le 24 avril 2007 Merci Gilles de ta suggestion, J'ai essayé, cela fonctionne bien dans des SCU parallèles au SCG, mais pas dans des SCU non parallèles.J'ai donc gardé le même algorithme que pour un segment droit que j'ai simplement appliqué à la tangente au point de sélection, au lieu de l'appliquer à la corde comme précédemment. Après des tests cela à l'aire de vouloir fonctionner correctement. J'ai trouvé aussi le moyen d'appliquer le paramètre "Par le point" de la fonction décaler. Le seul "Hic" qui reste est la gestion de l'erreur dans le cas d'un arc ou la valeur de décalage est plus grande que le rayon et que celui est décalé vers le centre. J'aurais voulu savoir si une fonction comme (vl-catch.... pourrait m'aider à résoudre simplement cette gestion d'erreur lors de l'appel à (vla-Offset car je n'ai encore jamais utilisé cette fonction. PS: J'ai mis à jour le code dans le 1er post Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius Lien vers le commentaire Partager sur d’autres sites More sharing options...
(gile) Posté(e) le 24 avril 2007 Partager Posté(e) le 24 avril 2007 Salut, Avec vl-catch-all-apply la routine continuera même si vla-offset génère une erreur, et vl-catch-all-error-p permet d'évaluer si vl-catch-all-apply en a généré une. On peut faire un truc du style : si erreur => envoie un message, sinon => change OFFSETDIST, et la routine continue : (entdel e_last) ... (if (vl-catch-all-error-p (vl-catch-all-apply 'vla-Offset (list (vlax-ename->vla-object e_last) (getvar "OFFSETDIST") ) ) ) (princ "\nL'objet ne peut pas être décalé.") (setvar "OFFSETDIST" (if (eq dis_offset "Through") -1 (abs (getvar "OFFSETDIST")) ) ) ) Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD Lien vers le commentaire Partager sur d’autres sites More sharing options...
bonuscad Posté(e) le 24 avril 2007 Auteur Partager Posté(e) le 24 avril 2007 OK J'avais déjà modifié le code car j'avais trouvé une solution, mais il n'est pas impossible que j'adopte la méthode que tu m'as proposé, plus simple... ;) Merci encore, je penses que le code est fiable maintenant. Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius Lien vers le commentaire Partager sur d’autres sites More sharing options...
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