29th September 2013, 09:55 PM | #1 |
Junior Member
Advanced member
Join Date: Sep 2004
Posts: 27
|
Align minimum of one object to maximum of another
Anyway to do this without having to resort to Vertex-Snap by Vertex ? Some objects don't have neighboring vertices, thus Snap by Vertex is a pain to do.
|
13th November 2013, 12:27 PM | #2 |
Junior Member
Member
Join Date: Aug 2013
Location: London UK
Posts: 22
|
Re: Align minimum of one object to maximum of another
Copy this code into a file and save as placeobject.tcl (in <ac3d directory>/scripts).
Code:
# code to place object at max of other object namespace eval placerelative { variable o1 "" ;# the ac3d tcl-reference to first object (a long integer) variable o2 "" ;# relative to this variable o1name "" variable o2name "" proc copyob {acobj kid} { # set object ident and name in variables either o1 or o2 (& o1name, o2name) # called from the menu object select created in "makeObjectPick" set ::placerelative::$acobj $kid set pobnm "::placerelative::${acobj}name" set $pobnm [ac3d object_get_name $kid] } proc makeObjectPick {w cue acobj} { # create a menu to select one of the objects attached to the world. set acobjfram [frame $w.$acobj] pack $acobjfram -side top set label [label $acobjfram.lab -text "$cue"] set mb [menubutton $acobjfram.obj1 -text "Select....."] set men [menu $mb.objects] $mb configure -menu $mb.objects pack $label $mb -side left foreach kid [ac3d object_get_children [ac3d get_world]] { set name [ac3d object_get_name $kid] $men add command -label $name -command "$mb configure -text {$name}; ::placerelative::copyob $acobj $kid" } } proc placeIt {op} { # place object o1 next to o2 with type = at_max, at_min, at_mid # and or at_midx, midy,midz to align one coordinate. global ::placerelative::o1 ::placerelative::o2 ac3d clear_selection ac3d object_select $::placerelative::o1 # get position and size of moved object set po1 [ac3d get_selection_centre] set sizo1 [ac3d get_selection_size] ac3d clear_selection ac3d object_select $::placerelative::o2 # get position and size of "relative to" object set posrel [ac3d get_selection_centre] set sizrel [ac3d get_selection_size] # calculate new object position to be ... - select according to OP ac3d clear_selection ac3d object_select $::placerelative::o1 set pos {} # puts "Pos type $op " foreach p1 $po1 prel $posrel srel $sizrel so1 $sizo1 idx {x y z} { set nup [expr {$prel}] switch -exact $op { "at_max_x" {if {$idx eq "x"} { set nup [expr {$prel+($srel+$so1)*.5}] } else { set nup $p1 } } "at_min_x" {if {$idx eq "x"} { set nup [expr {$prel-($srel+$so1)*.5}] } else { set nup $p1 } } "at_max_y" {if {$idx eq "y"} { set nup [expr {$prel+($srel+$so1)*.5}] } else { set nup $p1 } } "at_min_y" {if {$idx eq "y"} { set nup [expr {$prel-($srel+$so1)*.5}] } else { set nup $p1 } } "at_max_z" {if {$idx eq "z"} { set nup [expr {$prel+($srel+$so1)*.5}] } else { set nup $p1 } } "at_min_z" {if {$idx eq "z"} { set nup [expr {$prel-($srel+$so1)*.5}] } else { set nup $p1 } } "at_max" {set nup [expr {$prel+($srel+$so1)*.5}] } "at_min" {set nup [expr {$prel-($srel+$so1)*.5}] } "at_centre" { } default {set nup [expr {$prel+($srel+$so1)*.5}] } } lappend pos $nup } eval ac3d move_to $pos } proc placeAnObject {} { # interface to place an object relative to another object set tlname {.placeobject} if {![winfo exists $tlname]} { # tk_messageBox -message "No toplevel for placing object" toplevel $tlname # set ob [ac3d get_selected_objects] ;# if any # set firstob [lindex $ob 0] pack [frame $tlname.frob1] -side top makeObjectPick $tlname.frob1 "Object to move" o1 pack [frame $tlname.frob2] -side top makeObjectPick $tlname.frob2 "Object static" o2 pack [frame $tlname.operation] -side top pack [label $tlname.operation.ob1 -textvariable ::placerelative::o1name] -side left set mb [menubutton $tlname.operation.op -text {operation} ] set men [menu $tlname.operation.op.menu] foreach op {at_max at_min at_centre at_max_x at_max_y at_max_z at_min_x at_min_y at_min_z} { $men add command -label "$op" -command "$mb configure -text {$op}; ::placerelative::placeIt {$op}" } $tlname.operation.op configure -menu $tlname.operation.op.menu pack $mb -side left pack [label $tlname.operation.ob2 -textvariable ::placerelative::o2name] -side left } } .mbar.tools.menu add command -label "Place relative" -command "placerelative::placeAnObject" -underline 0 } Use the "Place relative" command under the tools menu and a new window appears. Choose the object to be moved and the object to place it relative to. Then choose the type of operation from the pull down menu between the objects names. The object to move will jump to the selected position; try 'at_max' and 'at_min' options. Option at_max places the minimum XYZ of moved object at maximum XYZ of relative object; option at_min places the maximum of the moved object at the minimum of the relative object.. Write your own positioning code based on proc "placeIt" to choose other types of positioning. |
|
|