(gile) Posté(e) le 24 août 2006 Posté(e) le 24 août 2006 Suite à ce sujet et à mes récentes découvertes sur les matrices de transformation, j'ai essayer d'un peu mieux aboutir le LISP que j'y proposais. Au delà du fait que la routine répare certains dysfonctionnements des commandes Diviser et Mesurer en 3D, elle répond à certains souhaits émis dans sujet cité. La longueur de l'objet sélectionné s'affiche sur la ligne de commande.Avec l'option bloc,- le choix du bloc se fait dans une liste déroulante- une option supplémentaire permet de choisir si le bloc est inséré par rapport au plan du SCU ou par rapport à celui de l'objet (SCO pour les objets 2D, plan défini par les dérivées première et seconde au point d'insertion pour les spline 3D, les hélices). Cette option n'est pas accessible pour les lignes et polylignes 3D (dérivée seconde = vecteur nul). Nouvelle version de getblock :- Possibilité de choisir un bloc non inséré dans le dessin à partir de la boite de dialogue standard d'AutoCAD- Réparé un bug avec l'insertion de points sur les lignes et polylignes 3D (25/08/06 10h50)- Pour lancer l'option "Bloc", taper ENTER, Espace ou clic droit à la place de "b" + ENTER- Possibilité d'entrer le nom du bloc (25/08/06 21h20) Version 1.1 (11/04/07)- affiche par défaut le dernier bloc inséré (INSNAME) Le fichier DCL à enregistrer sous getblock.dcl dans un dossier du chemin de recherche des fichiers de support. getblock:dialog{ label="Choisir un bloc"; initial_focus="bl"; :boxed_column{ :row{ :column{ spacer; :text{ label="Nom :"; alignment=left; } } :column{ :button{ label="Parcourir..."; key="wbl"; alignment=right; fixed_width=true; } spacer; } } :edit_box{ key="tp"; edit_width=25; } :popup_list{ key="bl"; edit_width=25; } spacer; } ok_cancel; } Le LISP,les sous routines sont communes aux deux commandes DIV3D et MES3D ;;; DIV3D et MES3D - Gilles Chanteau - 25/08/06 ;;; ;;; Fonctionnement similaire aux commandes DIVISER (_DIVIDE) et MESURER (_MEASURE) ;;; Les plus : ;;; - L'option "Bloc" permet l'insertion de bloc sur des objets "mesurables" quels que ;;; soient le SCO de l'objet et le SCU courant. ;;; - Une option supplémentaire : "Plan de référence pour l'insertion du bloc ?" ;;; permet de choisir si le bloc est inséré par rapport au plan XY du SCU courant ;;; [scu] ou par rapport à l'objet [Objet]. ;;; - Le choix du bloc se fait dans la liste déroulante d'une boite de dialogue. ;;; - La longueur de l'objet sélectionnée est affichée sur la ligne de commande. ;;; Getspace Retourne l'espace courant (Modèle ou Papier) (defun getSpace () (if (= (getvar "CVPORT") 1) (vla-get-PaperSpace (vla-get-ActiveDocument (vlax-get-acad-object)) ) (vla-get-ModelSpace (vla-get-ActiveDocument (vlax-get-acad-object)) ) ) ) ;;; Getblock (version 1.1) ;;; Retourne le nom du bloc entré ou choisi par l'utilisateur ;;; dans une liste déroulante de la boite de dialogue ou depuis la boite ;;; de dialogue standard d'AutoCAD ;;; Argument : le titre (string) ou nil (défaut : "Choisir un bloc") (defun getblock (titre / bloc n lst what_next dcl_id nom) (while (setq bloc (tblnext "BLOCK" (not bloc))) (setq lst (cons (cdr (assoc 2 bloc)) lst) ) ) (setq lst (acad_strlsort (vl-remove-if '(lambda (n) (= (substr n 1 1) "*")) lst) ) ) (setq dcl_id (load_dialog "Getblock.dcl")) (setq what_next 2) (while (>= what_next 2) (if (not (new_dialog "getblock" dcl_id)) (exit) ) (start_list "bl") (mapcar 'add_list lst) (end_list) (if titre (set_tile "box" titre) ) (or (and (setq n (vl-position (strcase (getvar "INSNAME")) (mapcar 'strcase lst) ) ) (setq nom (nth n lst)) ) (setq nom (car lst) n 0 ) ) (set_tile "bl" (itoa n)) (action_tile "bl" "(setq nom (nth (atoi $value) lst))") (action_tile "wbl" "(done_dialog 3)") (action_tile "tp" "(setq nom $value) (done_dialog 4)") (action_tile "accept" "(setq nom (nth (atoi (get_tile \"bl\")) lst)) (done_dialog 1)" ) (setq what_next (start_dialog)) (cond ((= what_next 3) (if (setq nom (getfiled "Sélectionner un fichier" "" "dwg" 0)) (setq what_next 1) (setq what_next 2) ) ) ((= what_next 4) (cond ((not (read nom)) (setq what_next 2) ) ((tblsearch "BLOCK" nom) (setq what_next 1) ) ((findfile (setq nom (strcat nom ".dwg"))) (setq what_next 1) ) (T (alert (strcat "Le fichier \"" nom "\" est introuvable.")) (setq nom nil what_next 2 ) ) ) ) ((= what_next 0) (setq nom nil) ) ) ) (unload_dialog dcl_id) nom ) ;;; V^V Retourne le produit vectoriel (vecteur) de deux vecteurs (defun v^v (v1 v2) (if (inters '(0 0 0) v1 '(0 0 0) v2) (list (- (* (cadr v1) (caddr v2)) (* (caddr v1) (cadr v2))) (- (* (caddr v1) (car v2)) (* (car v1) (caddr v2))) (- (* (car v1) (cadr v2)) (* (cadr v1) (car v2))) ) ) ) ;;; NORM_3PTS retourne le vecteur normal du plan défini par 3 points (defun norm_3pts (org xdir ydir / norm) (foreach v '(xdir ydir) (set v (mapcar '- (eval v) org)) ) (mapcar '(lambda (x) (/ x (distance '(0 0 0) norm))) (setq norm (v^v xdir ydir)) ) ) ;;; Transpose une matrice -Doug Wilson- (defun trp (m) (apply 'mapcar (cons 'list m)) ) ;;; Ang (defun ang (if (and ( ang (ang ) ) ;;; DivMesInsert Insère le bloc (ou le point) suivant les options choisies (defun DivMesInsert (/ norm deriv2 ang mat ydir) (if (/= scu "Scu") (cond ((member (vla-get-ObjectName obj) '("AcDbArc" "AcDbCircle" "AcDbEllipse" "AcDbPolyline" "AcDb2dPolyline" ) ) (setq norm (vlax-safearray->list (vlax-variant-value (vla-get-Normal obj)) ) ) ) ((not (member (vla-get-ObjectName obj) '("AcDbLine" "AcDb3dPolyline") ) ) (setq deriv2 (vlax-curve-getSecondDeriv obj ins_par ) ) (setq ang (ang ) ) (if ( (setq norm (norm_3pts '(0 0 0) deriv1 deriv2)) (setq norm (norm_3pts '(0 0 0) deriv2 deriv1)) ) ) ) ) (if nom (progn (if (= scu "Scu") (progn (if (= algn "Non") (setq ang (angle '(0 0 0) (trans (getvar "UCSXDIR") 0 ucszdir) ) ) (setq ang (angle '(0 0 0) (trans deriv1 0 ucszdir)) ) ) (setq mat (mapcar '(lambda (v) (trans v 0 ucszdir)) (list (list (cos ang) (- (sin ang)) 0) (list (sin ang) (cos ang) 0) '(0 0 1) ) ) ) ) (if (= algn "Non") (setq ydir (norm_3pts '(0 0 0) norm (getvar "ucsxdir")) mat (trp (cons (norm_3Pts '(0 0 0) ydir norm) (cons ydir (cons norm mat) ) ) ) ) (setq mat (trp (list (mapcar '(lambda (x) (/ x (distance '(0 0 0) deriv1)) ) deriv1 ) (norm_3pts '(0 0 0) norm deriv1) norm ) ) ) ) ) (vla-TransformBy (vla-InsertBlock (getspace) (vlax-3d-point '(0 0 0)) nom 1 1 1 0 ) (vlax-tmatrix (append (mapcar '(lambda (v1 v2) (append v1 (list v2)) ) mat ins_pt ) (list '(0 0 0 1)) ) ) ) (setvar "INSNAME" nom) ) (vla-addPoint (getspace) (vlax-3d-point ins_pt)) ) ) ;;; Std_vl_err Redéfinition de *error* (defun std_vl_err (msg) (if (= msg "Fonction annulée") (princ) (princ (strcat "\nErreur: " msg)) ) (vla-EndUndoMark (vla-get-ActiveDocument (vlax-get-acad-object)) ) (setq *error* m:err m:err nil ) (princ) ) ;;;******************************************************************;;; ;;; Div3D (defun c:div3D (/ AcDoc ucszdir ent obj pick long nb nom algn scu dist ins_pt ins_par deriv1 ) (vl-load-com) (setq m:err *error* *error* std_vl_err ) (setq AcDoc (vla-get-ActiveDocument (vlax-get-acad-object)) ucszdir (trans '(0 0 1) 1 0 T) ) (sssetfirst nil nil) (if (vl-catch-all-error-p (vl-catch-all-apply 'vla-getEntity (list (vla-get-Utility AcDoc) 'obj 'pick "\nChoix de l'objet à diviser: " ) ) ) (prompt "*Incorrect*") (progn (if (vl-catch-all-error-p (vl-catch-all-apply 'vlax-curve-getEndParam (list obj)) ) (prompt "\nL'objet ne peut pas être divisé.*Incorrect*") (progn (setq long (vlax-curve-getDistAtParam obj (vlax-curve-getEndParam obj) ) ) (prompt (strcat "\nLongueur de l'objet: " (rtos long))) (while (not (> 3268 nb 1)) (setq nb (getint "\nEntrez le nombre de segments ou : ") ) (if nb (if (not (> 3268 nb 1)) (prompt "\nNécessite un entier entre 2 et 32767, ou une option." ) ) (progn (setq nom (getblock nil)) (if nom (setq nb 2) (setq nb 0) ) ) ) ) (if nom (progn (initget "Oui Non") (setq algn (getkword "\nAligner le bloc avec l'objet ? [Oui/Non] : " ) nb 0 ) (if (not (member (vla-get-ObjectName obj) '("AcDbLine" "AcDb3dPolyline") ) ) (progn (initget "Objet Scu") (setq scu (getkword "\nPlan de référence pour l'insertion du bloc ? [Objet/Scu] : " ) ) ) (setq scu "Scu") ) (while (not (> 3268 nb 1)) (setq nb (getint "\nEntrez le nombre de segments: ")) (if (not (> 3268 nb 1)) (prompt "\nNécessite un entier entre 2 et 32767." ) ) ) ) ) (setq dist (/ long nb)) (vla-StartUndoMark AcDoc) (repeat (setq nb (1- nb)) (setq ins_pt (vlax-curve-getPointAtDist obj (* nb dist)) ins_par (vlax-curve-getParamAtDist obj (* nb dist)) deriv1 (vlax-curve-getFirstDeriv obj ins_par ) ) (DivMesInsert) (setq nb (1- nb)) ) (if (vlax-curve-isClosed obj) (progn (setq ins_pt (vlax-curve-getStartPoint obj) ins_par (vlax-curve-getStartParam obj) deriv1 (vlax-curve-getFirstDeriv obj ins_par ) ) (DivMesInsert) ) ) (vla-EndUndoMark AcDoc) ) ) ) ) (setq *error* m:err m:err nil ) (princ) ) ;;;******************************************************************;;; ;;; Mes3D (defun c:mes3D (/ AcDoc ucszdir obj pick long dist nom algn scu nb rest ins_pt deriv1) (vl-load-com) (setq m:err *error* *error* std_vl_err ) (setq AcDoc (vla-get-ActiveDocument (vlax-get-acad-object)) ucszdir (trans '(0 0 1) 1 0 T) ) (sssetfirst nil nil) (if (vl-catch-all-error-p (vl-catch-all-apply 'vla-getEntity (list (vla-get-Utility AcDoc) 'obj 'pick "\nChoix de l'objet à mesurer: " ) ) ) (prompt "*Incorrect*") (progn (if (vl-catch-all-error-p (vl-catch-all-apply 'vlax-curve-getEndParam (list obj)) ) (prompt "\nL'objet ne peut pas être mesuré.*Incorrect*") (progn (setq pick (vlax-curve-getClosestPointToProjection obj (trans (vlax-SafeArray->list pick) 1 0) (mapcar '- (trans (getvar "viewdir") 1 0) (trans '(0 0 0) 1 0) ) ) long (vlax-curve-getDistAtParam obj (vlax-curve-getEndParam obj) ) ) (prompt (strcat "\nLongueur de l'objet: " (rtos long))) (while (and (not (numberp dist)) (not nom)) (if (not (setq dist (getint "\nSpécifiez la longueur du segment ou : " ) ) ) (setq nom (getblock nil)) ) ) (if nom (progn (initget "Oui Non") (setq algn (getkword "\nAligner le bloc avec l'objet ? [Oui/Non] : " ) ) (if (not (member (vla-get-ObjectName obj) '("AcDbLine" "AcDb3dPolyline") ) ) (progn (initget "Objet Scu") (setq scu (getkword "\nPlan de référence pour l'insertion du bloc ? [Objet/Scu] : " ) ) ) (setq scu "Scu") ) (initget 7) (setq dist (getdist "\nSpécifiez la longueur du segment: ") ) ) ) (if ( (prompt "\nL'objet n'est pas assez long.") (progn (setq nb (fix (/ long dist))) (if ( (setq rest (rem long dist)) (setq rest nil) ) (vla-StartUndoMark AcDoc) (repeat nb (setq ins_pt (if rest (vlax-curve-getPointAtDist obj (+ (* (1- nb) dist) rest) ) (vlax-curve-getPointAtDist obj (* nb dist)) ) ins_par (if rest (vlax-curve-getParamAtDist obj (+ (* (1- nb) dist) rest) ) (vlax-curve-getParamAtDist obj (* nb dist)) ) deriv1 (vlax-curve-getFirstDeriv obj ins_par) ) (DivMesInsert) (setq nb (1- nb)) ) (vla-EndUndoMark AcDoc) ) ) ) ) ) ) (setq *error* m:err m:err nil ) (princ) )[Edité le 24/8/2006 par (gile)][Edité le 25/8/2006 par (gile)][Edité le 25/8/2006 par (gile)][Edité le 26/8/2006 par (gile)] [Edité le 11/4/2007 par (gile)] Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Bred Posté(e) le 24 août 2006 Posté(e) le 24 août 2006 Salut (gile) ...Une (petite) amélioration qui je suis sûr t'amuserais de faire ;) : le choix du bloc à insérer n'est pas forcément déjà insérer dans le dessin, mais le choix peut se faire aussi par rapport à un répertoire de bibliothèque .... .... je suis persuadé que tu n'es pas assez bon pour faire ça .... :P :P :P (... ou comment jouer sur la fierté d'un gars pour demander un service sans en avoir l'air ...) Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...
(gile) Posté(e) le 24 août 2006 Auteur Posté(e) le 24 août 2006 Salut Bred, Je pense que ça serait un excellent exercice pour toi. ;) Tu pourrais ajouter un bouton dans la boite de dialogue de getblock qui lancerait la fonction (getfiled ...) Jusqu'à quand veux tu que je te laisses chercher avant de donner une solution ? [Edité le 24/8/2006 par (gile)] Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Bred Posté(e) le 24 août 2006 Posté(e) le 24 août 2006 ... touché !!! ...j'avoue que je le chercherais volontier, mais j'ai vraiment du boulot par dessus la tête en ce moment... de plus les boite de dialogue dcl sont de domaine de l'inconnu pour moi, et je passe tellement de temps à déjà décortiqué de "simple" lisp que je met les boites de dialogues dcl de côté... Et puis c'est ta faute aussi, avec tous les cours/rxplications de lisp que tu donnes (fonctions récursives, matrices, ....) et les lisps que tu proposes (ainsi que Patrick_35) je suis balader dans tous les sens !!! donc je ne pense vraiment pas m'y pencher de si-tôt... Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...
(gile) Posté(e) le 24 août 2006 Auteur Posté(e) le 24 août 2006 Alors je ne te fais pas attendre plus longtemps, je modifie getblock (lsp et dcl) dans le premier message. Tu as raison, la gestion des boites de dialogue avec le DCL est plutôt ingrate, mais avec ObjectDCL ça devrait être plus facile. Sinon, si ça peut te rassurer, je suis largué par certains codes de Patrick_35 (et d'autres). Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Bred Posté(e) le 24 août 2006 Posté(e) le 24 août 2006 ... merci . Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...
Bred Posté(e) le 25 août 2006 Posté(e) le 25 août 2006 Salut (gile), Suggestion :Lors de la demande sur la ligne de commande Entrez le nombre de segments ou [bloc]:je comprends que tu ais voulu retrouver le même fonctionnement que la commande standard d'autocad, mais personnellement j'aime bien lorsqu'il y a des options à choisir d'avoir une option par "défaut en validation" , c'est à dire que ici, si tu valides sans rentrer de nombre de segment, il comprends que tu veux rentrer un nom de bloc... je ferait : (if (equal nb nil) (setq nb "Bloc")) ----------------------------------------------------------- Demande :N'y a t'il pas moyen, en plus de la posibilité d'aller chercher un fichiers que tu viens de rajouter, d'avoir une zone de texte "libre" où l'on taperait le nom d'un bloc existant (pas forcément dans la liste déroulante, donc déjà inséré) et en l'insérant ensuite avec (commande "-insert" ...) ou plûtot j'imagine que tu préfereras en vl du genre (vla-insertblock (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object))) ; (vlax-3d-point (trans pt 1 0)) Nom 1 1 1 ; (angle '(0 0 0) (trans (getvar "UCSXDIR") 0 (trans '(0 0 1) 1 0 T)))) Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...
(gile) Posté(e) le 25 août 2006 Auteur Posté(e) le 25 août 2006 Salut, J'ai effectivement cherché à reproduire le fonctionnement des commandes originelles en ce qui concerne la saisie des données. Mais comme je pense comme toi que c'est aussi une amélioration, je modifie le code, de toute façon, si l'utilisateur tapait Enter, espace ou faisait un clic droit par mégarde, l'option "Annuler" de la boite de dialogue getblock permet de ré-entrer dans la boucle pour spécifier le nombre de segments ou le la longueur des segments. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
(gile) Posté(e) le 25 août 2006 Auteur Posté(e) le 25 août 2006 J'avais oublié la deuxième remarque : pas forcément dans la liste déroulante, donc déjà inséré La liste déroulante contient tous les blocs de la collection qu'ils soient insérés ou non, donc je ne vois pas l'intérêt de la "case vide", la boite dialogue est faite pour éviter d'avoir à taper le nom du bloc. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Bred Posté(e) le 25 août 2006 Posté(e) le 25 août 2006 Salut, Si ils sont dans "la collection", cela veut dire qu'ils ont été déjà inséré à un moment ou à un autre... même si il ne sont pas "dans" le plan, il font parti de ce plans parceque insérer au moins une fois... (ou créé dedans)si par contre, je veux insérer un bloc qui n'a jamais été inséré dans le plan (donc ne faisant pas partie de la collection), que ce bloc fait parti d'un des repertoire déclaré comme tel dans les fichiers supports (ces blocs je peux les appeler au clavier en faisant -inserer(nomdubloc)(echx)(echy)(echz)(rot) (... en sachant que la plupart du temps les echelles sont à 1 ....) Avec ta routine, si je veux insérer un bloc il faut qu'il soit dans la collection,ou que j'aille le chercher dans un repertoire (ce qui est trés utile si je ne me souvient plus du nom du bloc)... mais si je connais le nom, et que je veux éviter de passer par l'étape de recherche dans les repertoires, je n'aurais qu'à taper le nom afin qu'il s'insert (il irait chercher le bloc dans mon fichier support de biblio...) Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...
(gile) Posté(e) le 25 août 2006 Auteur Posté(e) le 25 août 2006 Tu deviens un peu exigent, mais l'objection est acceptée ;) Je modifie à nouveau les codes. [Edité le 25/8/2006 par (gile)] Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Bred Posté(e) le 26 août 2006 Posté(e) le 26 août 2006 Tu deviens un peu exigent... ... mais j'espère ne pas être désobligeant ... :exclam: dans tout les cas merci !!!! ... mais je vais encore exagerer .... afin de comprende ce lisp, en parrallèle de tes explication sur les vecteurs et matrices, pourrais-tu m'expliquer quel est la logique (et la raison) dans ton lisp pour que tu utilises : le produit vectoriel (vecteur) de deux vecteurs puis le vecteur normal du plan défini par 3 points (en fait je pense que c'est pour définir le sens ET direction 3D, mais je ne suis pas certain de mon raisonnement) et Transpose une matrice ... ça, malgré ton explication sur les matrices dans un précedent post ça me laisse "pantois"... double merci Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...
(gile) Posté(e) le 26 août 2006 Auteur Posté(e) le 26 août 2006 mais j'espère ne pas être désobligeant ... Bien sûr que non, c'était une taquinerie ;) À la première question, je n'utilise pas le produit vectoriel puis le vecteur normal du plan défini par trois points, c'est pour calculer le vecteur normal du plan que j'utilise le produit vectoriel.En fait, j'ai décomposé la routine Norm_3pts en deux routines (pensant que c'était plus clair): - v^v qui retourne le produit vectoriel de deux vecteurs, soit un vecteur perpendiculaire aux deux vecteurs passés comme argument.- Norm_3pts dont les arguments sont des points, calcule les vecteurs du premier au deuxième et du premier au toisième point, puis appelle v^v pour trouver le vecteur normal à ces deux là et en calcule le vecteur unitaire (de norme 1). À la deuxième question, la transposition d'une matrice (faire passer les rangées en colonnes) appliquée à une matrice de transformation permet de trouver la matrice de transformation inverse : Matrice de rotation de 30° sur l'axe Z au point 0,0,0 :((0.866025 -0.5 0.0 0.0) (0.5 0.866025 0.0 0.0) (0.0 0.0 1.0 0.0) (0 0 0 1)) ou : 0.866 -0.5 0.0 0.00.5 0.866 0.0 0.00.0 0.0 1.0 0.00.0 0.0 0.0 1.0 La fonction trp (transpose) appliquée à la matrice précédente : (trp '((0.866025 -0.5 0.0 0.0) (0.5 0.866025 0.0 0.0) (0.0 0.0 1.0 0.0) (0 0 0 1))) retourne :((0.866025 0.5 0.0 0.0) (-0.5 0.866025 0.0 0.0) (0.0 0.0 1.0 0.0) (0 0 0 1)) ou : 0.866 0.5 0.0 0.0-0.5 0.866 0.0 0.00.0 0.0 1.0 0.00.0 0.0 0.0 1.0 qui est la matrice de transformation inverse : rotation de 330° (ou -30°) sur l'axe Z au point 0,0,0 C'est là un des intérêts de l'utilisation des matrices. [Edité le 26/8/2006 par (gile)] Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Bred Posté(e) le 26 août 2006 Posté(e) le 26 août 2006 merci pour tout Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...
(gile) Posté(e) le 26 août 2006 Auteur Posté(e) le 26 août 2006 Petite précision tout de même, dans l'exemple précédent, la transposition fonctionne sur la matrice complète parceque le déplacement (translation) est nul : vecteur 0,0,0 (trois premiers termes de la quatrième colonne) et peut être transposé avec la dernière rangée (0 0 0 1). Si le déplacement n'est pas nul, pour trouver la matrice de transformation inverse, on transpose la matrice de dimension 3X3 constituée des 3 premiers termes des trois première rangées (échelle et rotations) et on applique cette nouvelle matrice au vecteur de déplacement (3 premiers termes de la dernière colonne) avec la fonction mxv (voir la fonction ReverseMatrix dans le sujet sur les matrices). Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
(gile) Posté(e) le 7 septembre 2006 Auteur Posté(e) le 7 septembre 2006 Suite à une suggestion de Bonuscad ici, en remplaçant la routine DivMesInsert donnée dans le premier message de ce sujet, par celle ci-dessous, on peut insérer le bloc "BLK_MEASURE_CURVE" avec attribut incrémenté. Il faut toutefois que ce bloc existe dans la collection du dessin (ou gabarit) ou comme fichier .dwg (wbloc) pour pouvoir le récupérer avec la fonction getblock. Pour créer ce bloc il suffit de lancer la routine make_blk_measure qui se trouve au début du lien donné ci dessus. ;;; DivMesInsert Insère le bloc (ou le point) suivant les options choisies (defun DivMesInsert (/ norm deriv2 ang mat ydir ref) (if (/= scu "Scu") (cond ((member (vla-get-ObjectName obj) '("AcDbArc" "AcDbCircle" "AcDbEllipse" "AcDbPolyline" "AcDb2dPolyline" ) ) (setq norm (vlax-safearray->list (vlax-variant-value (vla-get-Normal obj)) ) ) ) ((not (member (vla-get-ObjectName obj) '("AcDbLine" "AcDb3dPolyline") ) ) (setq deriv2 (vlax-curve-getSecondDeriv obj ins_par ) ) (setq ang (ang ) ) (if ( (setq norm (norm_3pts '(0 0 0) deriv1 deriv2)) (setq norm (norm_3pts '(0 0 0) deriv2 deriv1)) ) ) ) ) (if nom (progn (if (= scu "Scu") (progn (if (= algn "Non") (setq ang (angle '(0 0 0) (trans (getvar "UCSXDIR") 0 ucszdir) ) ) (setq ang (angle '(0 0 0) (trans deriv1 0 ucszdir)) ) ) (setq mat (mapcar '(lambda (v) (trans v 0 ucszdir)) (list (list (cos ang) (- (sin ang)) 0) (list (sin ang) (cos ang) 0) '(0 0 1) ) ) ) ) (if (= algn "Non") (setq ydir (norm_3pts '(0 0 0) norm (getvar "ucsxdir")) mat (trp (cons (norm_3Pts '(0 0 0) ydir norm) (cons ydir (cons norm mat) ) ) ) ) (setq mat (trp (list (mapcar '(lambda (x) (/ x (distance '(0 0 0) deriv1)) ) deriv1 ) (norm_3pts '(0 0 0) norm deriv1) norm ) ) ) ) ) (setq ref (vla-InsertBlock (getspace) (vlax-3d-point '(0 0 0)) nom 1 1 1 0 ) ) (if (= nom "BLK_MEASURE_CURVE") (progn (vla-put-TextString (car (vlax-invoke ref 'getAttributes)) (if rest (rtos (- long (vlax-curve-getDistAtPoint obj ins_pt))) (rtos (vlax-curve-getDistAtPoint obj ins_pt)) ) ) (vla-ScaleEntity (car (vlax-invoke ref 'getAttributes)) (vlax-3d-point '(0 0 0)) (* 0.1 dist) ) ) ) (vla-TransformBy ref (vlax-tmatrix (append (mapcar '(lambda (v1 v2) (append v1 (list v2)) ) mat ins_pt ) (list '(0 0 0 1)) ) ) ) ) (vla-addPoint (getspace) (vlax-3d-point ins_pt)) ) ) [Edité le 7/9/2006 par (gile)] Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
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