PDA

View Full Version : Project centerline of cilinder on flat face [lisp]


Harry
08-17-2004, 02:08 AM
I like to project the centerline of a cilinder face on a flat face.

I made a dialog but got stuck on the translation of 3d to 2d coords.

To see what I mean, make a simple rectangle block with a cilinder hole in it and then start the dialoc below.


(sd-defdialog 'proj_center_dialog
:dialog-title "PROJECT CENTER OF HOLE"
:variables '(
(UI_FACE_HOLE
:selection (*sd-cylinder-seltype*)
:title "HOLE"
:prompt-text "SELECT FACE OF HOLE...")

(UI_FACE_BLOCK
:selection (*sd-face-seltype*)
:value-type :face
:title "Proj.Face"
:prompt-text "SELECT FACE OF BLOCK TO PROJECT CENTERLINE ON...")
);variables

:ok-action
'(proj_center)

:local-functions
'(
(proj_center ()
(progn
(let (a_part a_pntstruc_1 a_pntstruc_2 a_center a_dir a_pnt2d_1 a_pnt2d_2)
(setf a_part (sd-inq-parent-obj UI_FACE_HOLE))
(setf a_center (sd-cylinder-center (sd-inq-geo-props UI_FACE_HOLE :dest-space :global)) )
(setf a_dir (sd-cylinder-axis-dir (sd-inq-geo-props UI_FACE_HOLE :dest-space :global)) )

(DISPLAY "--")
(DISPLAY a_center)
(DISPLAY "--")

(setf a_pntstruc_1 (sd-proj-pnt-on-face UI_FACE_BLOCK a_center :source-space :local :sf-space t))
(setf a_pntstruc_2 (sd-proj-pnt-on-face UI_FACE_BLOCK (sd-vec-add a_center a_dir) :source-space :local :sf-space t))

(setf a_pnt2d_1 (make-gpnt2d
:x (sd-face-relax-pnt-u a_pntstruc_1)
:y (sd-face-relax-pnt-v a_pntstruc_1) ))

(setf a_pnt2d_2 (make-gpnt2d
:x (sd-face-relax-pnt-u a_pntstruc_2)
:y (sd-face-relax-pnt-v a_pntstruc_2) ))

(DISPLAY a_pnt2d_1)
(DISPLAY a_pnt2d_2)

(sd-call-cmds
(progn
(CREATE_WORKPLANE
:new
:owner "/"
:name "wp_proj_center"
:par_face :face
:face UI_FACE_BLOCK :face UI_FACE_BLOCK :done)

(C_LINE_INF
:two_points a_pnt2d_1 a_pnt2d_2)
);progn
);sd-call-cmds
);let
);progn
);proj_center
);lf

)



greetings Harry

Andy Poulsen
08-17-2004, 09:24 PM
Hi Harry,

It's actually easier to do than you think! :)

Here's some code that should do what you want (there's quite a bit of your code in it -- I just simplified it and changed the variable names to help identify their functions)...

(proj_center ()
(let ((face_center)
(axis_dir)
(face_center_wp) ;; will hold value of face_center in WP coords
(axis_dir_wp) ;; will hold value of axis_dir in WP coords
)
;; first, find the face center in global coords
(setf face_center
(sd-cylinder-center
(sd-inq-geo-props UI_FACE_HOLE :dest-space :global)) )
;; now find the face axis direction in global coords
(setf axis_dir (sd-cylinder-axis-dir
(sd-inq-geo-props UI_FACE_HOLE
:dest-space :global)) )

(display (format nil "face_center: ~A " face_center ))
(display (format nil "axis_dir: ~A " axis_dir ))

;; now create a workplane to project onto
(sd-call-cmds (CREATE_WORKPLANE
:new
:owner "/"
:name "wp_proj_center"
:par_face :face
:face UI_FACE_BLOCK
:done)
:success t
:failure nil ;; add this line so it won't stop if wp already exists
)

(display (format nil "current wp: ~A " (sd-inq-obj-pathname (sd-inq-curr-wp))))

;; now map our center and axis dir points into the wp's coords
(setq face_center_wp (sd-vec-xform
face_center
:source-space :global
:dest-space (or (sd-pathname-to-obj "/wp_proj_center")
(sd-inq-curr-wp))))
(setq axis_dir_wp (sd-vec-xform
(sd-vec-add face_center axis_dir)
:source-space :global
:dest-space (or (sd-pathname-to-obj "/wp_proj_center")
(sd-inq-curr-wp))))

(display (format nil "face_center_wp: ~A " face_center_wp ))
(display (format nil "axis_dir_wp: ~A " axis_dir_wp ))


;; finally, create the c_line using the u and v (i.e. not w) coords.
;; this is easily accomplished using sd-gpnt3d-to-2d, which
;; just eliminates the "z" component of a 3d vector (which
;; in this case is the "w" component.
(when (sd-inq-curr-wp)
(sd-call-cmds (C_LINE_INF
:two_points
(sd-gpnt3d-to-2d face_center_wp)
(sd-gpnt3d-to-2d axis_dir_wp)
)
);sd-call-cmds
);when
);let
)

I hope the comments help -- if you have any questions, just ask!

Good luck!

Andy

Harry
08-19-2004, 04:17 AM
Originally posted by asp
Hi Harry,

It's actually easier to do than you think! :)

<...>

I hope the comments help -- if you have any questions, just ask!

Andy

Thanks for your help, it is indeed easier then I thought.

I made the code running like I wanted.
A little question about setting a variable in a dialog:


(sd-defdialog 'proj_center_dialog
:dialog-title "PROJECT HOLECENTER"
:variables '(
(WP_TYPE
:value-type :string
:initial-visible nil
)

(UI_WP_TYPE_NEW
:value-type :grouped-boolean
:title "NEW"
:after-input (store_type "NEW"))

(UI_WP_TYPE_CURRENT
:value-type :grouped-boolean
:title "CURRENT"
:after-input (store_type "CURRENT"))

);variables

:mutual-exclusion '(UI_WP_TYPE_NEW UI_WP_TYPE_CURRENT)

:precondition '(
if (sd-inq-curr-wp)
(progn
(DISPLAY "c")
;(sd-set-variable-status 'UI_WP_TYPE_CURRENT :on)
:ok
);progn
;else
(progn
(DISPLAY "n")
;(sd-set-variable-status 'UI_WP_TYPE_NEW :on)
:ok
);progn
);precondition

:ok-action
'(progn
(if (string= UI_WP_TYPE_CURRENT t) (store_type "CURRENT"))
(if (string= UI_WP_TYPE_NEW t) (store_type "NEW"))

(DISPLAY WP_TYPE)
(DISPLAY UI_WP_TYPE_CURRENT)
(DISPLAY UI_WP_TYPE_NEW)

;do other stuff....

)

:local-functions '(
(store_type (type_of_wp)
(progn
(setf WP_TYPE type_of_wp)

);progn
);store_type
);lf

)


I know I have to use the command

(sd-set-variable-status 'UI_WP_TYPE_CURRENT :on)

to switch the element to true, but what am I missing right now?

The manual isn't very clear about it.... :(

dorothea
08-19-2004, 04:59 AM
I know I have to use the command

(sd-set-variable-status 'UI_WP_TYPE_CURRENT :on)

to switch the element to true, but what am I missing right now?

The manual isn't very clear about it.... :(

You have to say, what you want do with the variable. Changing the value is done by parameter :value, changing the enable status is done by :enable. and so on

Perhaps your code should look like this:
(sd-set-variable-status 'UI_WP_TYPE_CURRENT :value :on)

Dorothea

Harry
08-19-2004, 05:16 AM
...
Perhaps your code should look like this:
(sd-set-variable-status 'UI_WP_TYPE_CURRENT :value :on)
...
[/B]

That doesn't work, it gives an error message:

[LISP error: Other-keys are not allowed.]

I can not find an example of how to set a value to a boolean var.

dorothea
08-19-2004, 05:29 AM
Hi Harry,

I didn't try out, what kind of value your variable takes. For sure you have to find the correct syntax fitting to the dialog.
You can find it out by starting a recorder file and calling your dialog. Press the button of interest and have a look into the written recorder, what syntax is there. This value take and add after the keyword :value instead of :on.

Dorothea

Harry
08-19-2004, 05:40 AM
Originally posted by dorothea
Hi Harry,

I didn't try out, what kind of value your variable takes. For sure you have to find the correct syntax fitting to the dialog.
You can find it out by starting a recorder file and calling your dialog. Press the button of interest and have a look into the written recorder, what syntax is there. This value take and add after the keyword :value instead of :on.

Dorothea

hello Dorothea,

I am sorry to tell you that recording the action doesn't give any info. I swithed serveral times between the two buttons and this is the result:

proj_center_dialog
:ui_wp_type_current
:ui_wp_type_new
:ui_wp_type_current
:ui_wp_type_new
complete

thus recording doesn't help me this time.

Harry

dorothea
08-19-2004, 05:57 AM
Sorry, I've overseen that your variable is mutual-exclusion. In such a case you have to use the value t or nil after.
There is something more special to it:
You need to reset all other variables of the mutual-exclusion group manually. Just to this by
(setq UI_WP_TYPE_NEW nil)

Hope now it's working!

Dorothea

Andy Poulsen
08-19-2004, 06:25 AM
Hi Harry,

one other thing you can do to simplify this and avoid setting the variables manually is to make the dialog think the user specified the change (i.e. that the user specified the change by typing into the command area). In your code where you used to have

;; note that for a BOOLEAN variable you need to use t or nil, not :on
(sd-set-variable-status 'UI_WP_TYPE_CURRENT :value :t)

you could use

(oli::put-buffer ":UI_WP_TYPE_CURRENT t")

which should do the cleanup work on the mutual-exclusion variables for you.

When setting dialog variables, one of the main differences between using (sd-set-variable-status ...) and using either (setq ...) or (setf ...) is that (sd-set-variable-status is designed to run the other processing commands associated with it (such as :after-input). The simple forms of setq/setf do not. Why the above code using (sd-set-variable-status 'UI_WP_TYPE_CURRENT :value t) doesn't automatically fix the mutual-exclusion variables is puzzling -- it certainly appears that it should (but the put-buffer workaround may do what you need).

I hope this helps!

andy

Harry
08-31-2004, 01:19 AM
(oli::put-buffer ":UI_WP_TYPE_CURRENT t")

...

I hope this helps!
...


It realy did!, Thank you Andy for the time you put in my problem.