objects as line knots

Become a member of the CGSociety

Connect, Share, and Learn with our Large Growing CG Art Community. It's Free!

Thread Tools Display Modes
  06 June 2011
objects as line knots


i was wondering if i could draw a line that would have as knots these boxes i have created in the image but the line would Start and End to the boxes that i would choose. But it needs to make it through the other box by travelling allong the boxes in 3D space and not 2D (like someone could guess from the image). I dont know in which theories is this based in order to code it in Maxscript bt if someone could tell me what do i need to know i could write it myself.

hope i made my point clear! i would appreciate any idea .
thank you

ps: i assume that maybe the line would choose each time the closest box (or the box between a specified range) in order to climb till the other box
  06 June 2011

--Author: Mike Burgoyne
global StructureFLOAT
local newOBJ
local splineArray = #()
try (cui.unregisterDialogBar StructureFLOAT) catch()  -- If already registered, then unregister.
try (closeRolloutFloater StructureFLOAT) catch() -- If already open, then close.
rollout Structure "Structure Maker"
group "Spline Controls"
  spinner rth "Spline Thickness: " type:#float width:100 align:#right enabled:true
  spinner stepsSP "Int Steps: " type:#integer width:100 align:#right enabled:true
button rScript "Run Script" enabled:true
button deleteS "Delete" enabled:false

on rScript pressed do (
 if $ == undefined then 
  messagebox "No objects are selected, Please select some objeccts"
deleteS.enabled = true
posArray = #() -- where to collect Point3 val's
-- step 1: collect object position
 count = selection.count
 temp = for i = 1 to count collect
 append posArray temp
for data in posArray do
 sp = splineShape render_renderable:true render_displayRenderMesh:true
 sp.render_thickness.controller = rth.controller = bezier_float ()
 sp.steps = stepsSP.value
 addnewSpline sp
 append splineArray sp
 for k in data do
  addKnot sp 1 #smooth #curve k
 updateShape sp
 on deleteS pressed do 
  for i = 1 to splineArray.count do delete splineArray[i]--loop through the array and delete each object in it
  splineArray = #() --empty the array
 StructureFLOAT = newRolloutFloater "Structure Maker" 200 210
 addRollout Structure  StructureFLOAT

I created this to draw a spline connecting selected objects. You will have to modify it a bit but it should help you on to the right path I hope.
  06 June 2011
hi viro,
i have found the answer!
the problem was not how you could connect a group of objects together with lines but to test recursively for the shortest path between two objects that belong to a higher amount of objects . but thank you also for the script :P
  06 June 2011
Matter of speaking,
do you know (or someone else who reads this) what are the changes in Maxscript between 2010/2011, and 2012 ? i got a script written in 2010 or 11 and i was always having an Runtime error expression all the time when i run the script in 2012. but the code was completely correct.
  06 June 2011
Originally Posted by aca88: Matter of speaking,
do you know (or someone else who reads this) what are the changes in Maxscript between 2010/2011, and 2012 ? i got a script written in 2010 or 11 and i was always having an Runtime error expression all the time when i run the script in 2012. but the code was completely correct.

see mxs help What is New in MAXScript in 3ds Max...

if you want to get someone's help show your code and error messages...
  06 June 2011
i saw the documentation but as im studying maxscript for only 6 - 7 months, i cant really understand which things might have changed..
here is the code that i couldnt run.

--code written by Garp
global rltBestVerticalPath
try destroyDialog rltBestVerticalPath catch()

struct path_data (

obj1, obj2, -- end objects
tol = 0.5, -- min z value between levels

-- sanity check
fn is_valid = (
return case of (
(NOT obj1.isSelected): (
messageBox (obj1.name + " not in selection")
(NOT obj2.isSelected): (
messageBox (obj2.name + " not in selection")
(abs(obj1.center.z - obj2.center.z) < tol): (
messageBox (obj1.name + " and " + obj2.name + " on same level")
default: true

-- sort object list by z position
obj_arr = selection as array,
fn zcomp obj1 obj2 = ( obj1.center.z - obj2.center.z ),
fn sort_obj_arr = ( qsort obj_arr zcomp ),

-- helper
fn get_pos i = ( obj_arr[i].center ),

-- split object list into levels
levels_arr = #(),
fn fill_levels_arr = (
local cnt = obj_arr.count
local ind = 1
while ind <= cnt do (
local curr_z = (get_pos ind).z
local curr_level = #{}
while ind <= cnt AND (get_pos ind).z < curr_z + tol do
append curr_level ind
ind += 1
append levels_arr curr_level

-- index of level in levels_arr from index in obj_arr
fn which_level i = (
for ba = 1 to levels_arr.count do
if findItem levels_arr[ba] i != 0 do
return ba
return 0 -- should never get there

best_path = #{},
bottom_ind = 0,
top_ind = 0,
bottom_level = 0,
top_level = 0,
min_dist = 1000000,

-- initialize data needed to find path
fn init_data = (
best_path = #{findItem obj_arr obj1, findItem obj_arr obj2}
bottom_ind = (best_path as array)[1]
top_ind = (best_path as array)[2]
bottom_level = which_level bottom_ind
top_level = which_level top_ind

-- search recursively for shortest path
fn find_path path dist = (
local last_ind = (path as array)[path.numberSet - 1]
local last_pos = get_pos last_ind
local last_level = which_level last_ind
if path.numberSet != top_level - bottom_level + 1 then (
for i in levels_arr[last_level + 1] do
find_path (path + #{i}) (dist + distance last_pos (get_pos i))
) else (
dist += distance last_pos (get_pos top_ind)
if dist < min_dist do (
min_dist = dist
best_path = path + #{top_ind}

-- do it, finally
fn pos_list = (
if is_valid() do (
if top_level - bottom_level > 1 do
find_path best_path 0
return for i in best_path collect get_pos i
return #()

) -- end struct best_path

-- find best path and create it
fn make_path obj1 obj2 tol smooth:true = (
local knots_arr = (path_data obj1 obj2 tol).pos_list()
if knots_arr.count != 0 do (
local sh = splineShape pos:((obj1.center + obj2.center) / 2)
addNewSpline sh
if smooth then (
knot_type = #smooth
seg_type = #curve
) else (
knot_type = #corner
seg_type = #line
for kn in knots_arr do
addKnot sh 1 knot_type seg_type kn
updateShape sh

rollout rltBestVerticalPath "Vertical Path"
fn filt obj = obj.isSelected
pickButton pb1 "Pick Object 1" filter:filt autoDisplay:true
pickButton pb2 "Pick Object 2" filter:filt autoDisplay:true
spinner tol "Tolerance:" range:[0, 100, 0.5]
button make "Make Path"
radioButtons sh_type labels:#("Smooth", "Linear")

on make pressed do (
local obj1 = pb1.object
local obj2 = pb2.object
if NOT obj1.isSelected OR NOT obj2.isSelected then
messageBox "Do not deselect!"
else make_path obj1 obj2 tol.value smooth:(sh_type.state == 1)
createDialog rltBestVerticalPath

and the error messages:
-- Error occurred in init_data(); filename: G:\....\; position: 2609; line: 80

-- called in pos_list(); filename: G:\......\; position: 3534; line: 105

-- called in make_path(); filename: G:\......\; line: 118

-- called in make.pressed(); filename: G:\...\; position: 5080; line: 150

>> MAXScript Rollout Handler Exception:
-- Unknown system exception <<

Last edited by aca88 : 06 June 2011 at 09:16 PM.
  06 June 2011
i run you code in max 2010 and 2012. it doesn't crash. i didn't test its functionality but at least it loads without any error message.

PS. Please put your code between "code" tags...

Last edited by denisT : 06 June 2011 at 04:28 PM.
  06 June 2011
i dont know how iits done..

about the code. yes its not a problem to load it. once you press the button it throws the errors i posted.
  06 June 2011
Originally Posted by aca88: i dont know how iits done..

about the code. yes its not a problem to load it. once you press the button it throws the errors i posted.

in MAX 2012 return expression is broken. avoid using it.
see http://forums.cgsociety.org/showpos...955&postcount=2
  07 July 2011
oh right! thanks alot.
  07 July 2011
Thread automatically closed

This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.
CGTalk Policy/Legalities
Note that as CGTalk Members, you agree to the terms and conditions of using this website.
Thread Closed share thread

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

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Society of Digital Artists

Powered by vBulletin
Copyright 2000 - 2006,
Jelsoft Enterprises Ltd.
Minimize Ads
Forum Jump

All times are GMT. The time now is 06:21 PM.

Powered by vBulletin
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.