Go Back   AC3D Forums > General > AC3D General
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

Thread Tools Display Modes
Old 29th September 2013, 09:55 PM   #1
Junior Member
Advanced member
Join Date: Sep 2004
Posts: 27
Default 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.
dre99gsx is offline   Reply With Quote
Old 13th November 2013, 12:27 PM   #2
Junior Member
Geoffm's Avatar
Join Date: Aug 2013
Location: London UK
Posts: 22
Default 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 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
Then launch ac3d and create 2 or more objects (I used a cube and a sphere).

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.
Geoffm is offline   Reply With Quote

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

All times are GMT -4. The time now is 09:58 PM.

AC3D Forum
(C) Inivis Limited 2020