CGTalk > Software > Maxon Cinema 4D
Login register
Thread Closed share thread « Previous Thread | Next Thread »  
 
Thread Tools Search this Thread Display Modes
Old 02-08-2013, 06:39 AM   #1
mogh
just hit render once more
 
mogh's Avatar
portfolio
Jan Weigand
Dipl. Industrial Designer
Fendt Traktors
Kaufbeuren, Germany
 
Join Date: Mar 2004
Posts: 626
Send a message via ICQ to mogh Send a message via MSN to mogh
Scripting: Python: Trouble with raycolider and matrixes

I started to dive into the raycolider utility from python and the first steps are made, but after cleaning the code and trying to evaluate which object is nearest to a start point I get weird koordniates from raycolider.

As you can see in the screenshot, the collision point of the initial target is ok, but from the obviously closer cube the collision point is somewhere in free space. I painted where it should be.
Code:
import c4d from c4d import gui from c4d.documents import GetActiveDocument from c4d import utils def GetNextObject(op): if not op: return if op.GetDown(): return op.GetDown() while op.GetUp() and not op.GetNext(): op = op.GetUp() return op.GetNext() def numberofobjects(op): all_list = list() while op: all_list.append(op) op = GetNextObject(op) return all_list def GetActiveObjects(doc): lst = list() op = doc.GetFirstObject() while op: if op.GetType() == 5100: # get all poly objects lst.append(op) op = GetNextObject(op) return lst # create nulls for visualizing the hitpos def create_null (coordinates, null_name): mynull = c4d.BaseObject(c4d.Onull) mynull[c4d.ID_BASEOBJECT_USECOLOR] = True mynull[c4d.ID_BASEOBJECT_COLOR] = c4d.Vector(255,0,0) mynull.SetAbsPos(coordinates) mynull.SetName(null_name) doc.InsertObject(mynull) return def firerayat (start, direction, length, optemp_test): # startpoint, direction, length, object to colide collider = c4d.utils.GeRayCollider() collider.Init(optemp_test, True) #force cache rebuild with true did_intersect = collider.Intersect(start.GetAbsPos(), direction, length) if did_intersect: create_null(collider.GetNearestIntersection()["hitpos"], optemp_test.GetName()) # creates null objects at the hitpos to visualize for debugging return collider.GetNearestIntersection()["distance"] else: return def raylength (startray, endray): return (startray.GetAbsPos() - endray.GetAbsPos()).GetLength() def ray_direction (start, optarget): return -(start.GetAbsPos() - optarget.GetAbsPos()).GetNormalized() def main(): c4d.CallCommand(13957) # Konsole löschen now = c4d.GeGetTimer() # start stopwatch if GetActiveDocument(): doc = GetActiveDocument() if doc.GetFirstObject(): c4d.StatusSetSpin() op = doc.GetFirstObject() myobject = op all_objects = numberofobjects(op) # list off all objects counter = len(all_objects) secondcounter = 0 c4d.StatusSetText ('%s Objects are processed.' %(counter)) opactive = None else: print "Error: No Objects" return False else: print "Error: No Document" return False opstart = doc.SearchObject("Start") optarget = doc.SearchObject("Target") lst = GetActiveObjects(doc) print "Polygon Obects: ", len(lst) hit_or_tested = [] never_hit = [] # delet all Nulls exept my start this is just for debugging n = 0 while n < len(all_objects): optempdelete = all_objects[n] if optempdelete.GetType() == 5140 and not optempdelete.GetName() == "Start": optempdelete.Remove() n = n+1 c4d.EventAdd() # end length = raylength(optarget, opstart) # two times just in case direction = ray_direction(opstart, optarget) print "Ray length: ", length print "Direction: ", direction print "-------------------------------------------------------------" temp_distance_list = [] temp_op_tested_list = [] i = 0 while i < len(lst): optemp = lst[i] distance = None temp_op_tested_list.append(optemp) distance = firerayat(opstart, direction, length, optemp) # target and testobject check ???? print optemp.GetName(), ": Collision at length: ", distance temp_distance_list.append(distance) i = i+1 nearest_distance = min(x for x in temp_distance_list if x is not None) print nearest_distance index_of_list = temp_distance_list.index(nearest_distance) print "Nearest Object: ", temp_op_tested_list[index_of_list].GetName() print "-------------------------------------------------------------" print temp_op_tested_list print temp_distance_list print "-------------------------------------------------------------" print 'END OF SCRIPT %s ms ' %(c4d.GeGetTimer() - now) c4d.EventAdd() c4d.StatusClear() if __name__=='__main__': main()


I think the trouble is somewhere here:
snippet from above ...
Code:
def firerayat (start, direction, length, optemp_test): # startpoint, direction, length, object to colide collider = c4d.utils.GeRayCollider() collider.Init(optemp_test, True) #force cache rebuild with true, dont know if it helps did_intersect = collider.Intersect(start.GetAbsPos(), direction, length) if did_intersect: create_null(collider.GetNearestIntersection()["hitpos"], optemp_test.GetName()) # creates null objects at the hitpos to visualize for debugging return collider.GetNearestIntersection()["distance"] else: return def raylength (startray, endray): return (startray.GetAbsPos() - endray.GetAbsPos()).GetLength() #is this ok? def ray_direction (start, optarget): return -(start.GetAbsPos() - optarget.GetAbsPos()).GetNormalized() #is this right?


If you want to test the above script put a Null called "Start" and some randomly placed polygon objects one called Target in your scene.

The script puts Null Objects at the collision points but the AbsSpace does not match or something entirely different ... I am stuck at the moment.

Any Ideas?
Attached Images
File Type: png screenshot_all.png (25.2 KB, 15 views)
__________________
R17 Visualize - Flickr Album - Website

Last edited by mogh : 02-08-2013 at 07:56 AM.
 
Old 02-08-2013, 01:06 PM   #2
littledevil
Meh
 
littledevil's Avatar
portfolio
Ferdinand
Germany
 
Join Date: Aug 2002
Posts: 616
i will take a closer look at it later, at the first look the code looks ok, just one thing.
the absolute coordinates are NOT the world coordinates. abs/rel coords are tied to
the freeze coords system. calculating a normal out of two coords in local space does
not really make sense.

you are trying to do this object culls object thing, right ?

Last edited by littledevil : 02-08-2013 at 01:12 PM.
 
Old 02-08-2013, 01:11 PM   #3
Darter
Positive buoyancy
 
Darter's Avatar
David Wickenden
Ballina, Australia
 
Join Date: Nov 2003
Posts: 1,221
I haven't had time to test the script but one issue appears to be the coordinate space used for the ray collison calculation.

The start point and ray direction passed to Intersect() must be in the coordinate space of the object passed to Init(). This is 'optemp' in the while loop.

The inverted global matrix of 'optemp' must be multiplied with the global positions of the start and end objects, e.g.
Code:
startPoint = ~optemp.GetMg() * opstart.GetMg().off

This will involve some restructuring of your code.
 
Old 02-08-2013, 02:18 PM   #4
mogh
just hit render once more
 
mogh's Avatar
portfolio
Jan Weigand
Dipl. Industrial Designer
Fendt Traktors
Kaufbeuren, Germany
 
Join Date: Mar 2004
Posts: 626
Send a message via ICQ to mogh Send a message via MSN to mogh
Darter your code works somehow, now i have points floating somewhere in space, need to check my nulls generation two - I hate matrices can't wrap my head around it ---- but I am on track again

yes little devil I'am trying to get the impossible done ...

which me luck ---

Update:
Code:
def create_null (coordinates, null_name, optemp_test): print coordinates, optemp_test wc = ~optemp_test.GetMg() * coordinates print wc mynull = c4d.BaseObject(c4d.Onull) mynull[c4d.ID_BASEOBJECT_USECOLOR] = True mynull[c4d.ID_BASEOBJECT_COLOR] = c4d.Vector(255,0,0) mynull.SetAbsPos(coordinates) mynull.SetName(null_name + " Point") doc.InsertObject(mynull) return


this is oviusly wrong ... but how do i transfer the local Matrix to the other Nulls representing a position in my c4D scene? I read matrix fundamentals 5 times and still can't understand how to tackle my Nulls ...
__________________
R17 Visualize - Flickr Album - Website

Last edited by mogh : 02-08-2013 at 02:34 PM.
 
Old 02-08-2013, 07:16 PM   #5
littledevil
Meh
 
littledevil's Avatar
portfolio
Ferdinand
Germany
 
Join Date: Aug 2002
Posts: 616
obj_global_matrix = parent_global_matrix * obj_local_matrix,

but again , SetAbsPosition is local space, which is correct, as you do insert the
new nulls under your root null, so i do not really understand your question, i guess
 
Old 02-08-2013, 11:03 PM   #6
Darter
Positive buoyancy
 
Darter's Avatar
David Wickenden
Ballina, Australia
 
Join Date: Nov 2003
Posts: 1,221
You've gone the wrong way. The hit position is converted from goal object to global coordinates like this:
Code:
def create_null (coordinates, null_name, optemp): wc = optemp.GetMg() * coordinates mynull = c4d.BaseObject(c4d.Onull) mynull[c4d.ID_BASEOBJECT_USECOLOR] = True mynull[c4d.ID_BASEOBJECT_COLOR] = c4d.Vector(255,0,0) mynull.SetAbsPos(wc) mynull.SetName(null_name) doc.InsertObject(mynull) return

The start point and ray direction still needed to be converted to goal object coordinate space:
Code:
def get_ray(start_obj, end_obj, goal): start = ~goal.GetMg() * start_obj.GetMg().off end = ~goal.GetMg() * end_obj.GetMg().off return {'ray_p' : start, 'ray_length' : (end - start).GetLength(), 'ray_dir' : (end - start).GetNormalized()}

The updated script seems to be working okay with various hierarchy configurations.

Quote:
Originally Posted by Little_Devil
obj_global_matrix = parent_global_matrix * obj_local_matrix

I'm aware of the calculation under Freeze Transformation in the SDK but find that GetMg() usually suffices. Most usage examples on Plugin Cafe since R12 support this.
 
Old 02-09-2013, 03:26 PM   #7
mogh
just hit render once more
 
mogh's Avatar
portfolio
Jan Weigand
Dipl. Industrial Designer
Fendt Traktors
Kaufbeuren, Germany
 
Join Date: Mar 2004
Posts: 626
Send a message via ICQ to mogh Send a message via MSN to mogh
Thanks to both of you I did already incoporate the changes and streamlined it even more.

@Darter: Are you returning a list of lists with the get_ray def?

How do I create a List of Lists (e.g. Object : Distance) and the get the Min Value with the coresponding Object.

At the moment I have two lists which are stored seperatly and I have to get the ID of List one and the get the object with the ID of List Two. Is there a better way to do this ?


kind regards
__________________
R17 Visualize - Flickr Album - Website
 
Old 02-11-2013, 08:15 PM   #8
Darter
Positive buoyancy
 
Darter's Avatar
David Wickenden
Ballina, Australia
 
Join Date: Nov 2003
Posts: 1,221
get_ray() returns a dictionary.
 
Old 02-11-2013, 09:05 PM   #9
mogh
just hit render once more
 
mogh's Avatar
portfolio
Jan Weigand
Dipl. Industrial Designer
Fendt Traktors
Kaufbeuren, Germany
 
Join Date: Mar 2004
Posts: 626
Send a message via ICQ to mogh Send a message via MSN to mogh
Thanks Darter.


i found a inconsistancy between
R14 and R13 of the get Ray function

R13 works but in R14 it seems as if the direction is the opposite but nevertheless the script gives positive hits ... weird ...

have to go to bed ... but I am already excluding obects yay
good night
__________________
R17 Visualize - Flickr Album - Website
 
Old 02-12-2013, 02:19 PM   #10
mogh
just hit render once more
 
mogh's Avatar
portfolio
Jan Weigand
Dipl. Industrial Designer
Fendt Traktors
Kaufbeuren, Germany
 
Join Date: Mar 2004
Posts: 626
Send a message via ICQ to mogh Send a message via MSN to mogh
forget the previous post, I seem to have broken it somewhere else on the code ...



suddenly not the nearest object but all objects are considerated as a near object and then the script jumps over all the other loops because the list "hit_list" was already filled with all objects in the scene.

FYI:
To get that script going you only need a 2 point spline called "ray" and some poly objects to fire at. The rest is generated automatically.

Code:
import c4d from c4d import gui from c4d.documents import GetActiveDocument from c4d import utils # import math def GetNextObject(op): if not op: return if op.GetDown(): return op.GetDown() while op.GetUp() and not op.GetNext(): op = op.GetUp() return op.GetNext() def numberofobjects(op): all_list = list() poly_list = list() while op: all_list.append(op) if op.GetType() == 5100 and op.GetName() != "Start Point Cloud": # get all poly objects poly_list.append(op) op = GetNextObject(op) return {'all_objects_list' : all_list, 'polygon_obj_list' : poly_list } def find_layer(layername): root = doc.GetLayerObjectRoot() #Gets the layer manager myLayersList = root.GetChildren() foundname = False for lname in myLayersList: if lname.GetName() == str(layername): return lname def create_layer(name, color, display_seen): root = doc.GetLayerObjectRoot()#Gets the layer manager c4d.CallCommand(100004738) #create new layer mynewLayersList = root.GetChildren() # get the new list newlayer = mynewLayersList[-1] # get the last index of a list in this case layer newlayer[c4d.ID_LAYER_COLOR] = color # Sets layer color newlayer.SetName(name) # Sets layer name newlayer[c4d.ID_LAYER_VIEW] = display_seen #set layer view setting newlayer[c4d.ID_LAYER_RENDER] = display_seen #set layer render setting return newlayer def create_sphere(sub, radius): obj = c4d.BaseObject(c4d.Osphere) obj[c4d.PRIM_SPHERE_RAD] = radius obj[c4d.PRIM_SPHERE_SUB] = sub obj[c4d.PRIM_SPHERE_TYPE] = 4 obj[c4d.PRIM_SPHERE_PERFECT] = False obj.SetName("Start Point Cloud") # obj.SetMg(c4d.Matrix(c4d.Vector(1,1,1))) doc.InsertObject(obj) # Insert object in document obj.SetBit(c4d.BIT_ACTIVE) c4d.CallCommand(12236) # Grundobjekt konvertieren # obj.Message(c4d.MSG_UPDATE) newobj = doc.SearchObject("Start Point Cloud") create_display_tag(newobj) p_positions = newobj.GetAllPoints() """ for p in p_positions: print p_positions.index(p), p, obj.GetUpMg() p_positions[p_positions.index(p)] = obj.GetUpMg()*p # gloabl coordinates #print p_positions[p_positions.index(p)] """ # newobj.Remove() obj.DelBit(c4d.BIT_ACTIVE) c4d.EventAdd() # Send global event message return p_positions def create_display_tag(myobject): mytag = myobject.MakeTag(c4d.Tdisplay) mytag[c4d.DISPLAYTAG_AFFECT_DISPLAYMODE] = True mytag[c4d.DISPLAYTAG_SDISPLAYMODE] = 6 return # create nulls for visualizing the hitpos def create_null (coordinates, null_name, optemp_test): wc = optemp_test.GetMg() * coordinates mynull = c4d.BaseObject(c4d.Onull) mynull[c4d.ID_BASEOBJECT_USECOLOR] = True mynull[c4d.ID_BASEOBJECT_COLOR] = c4d.Vector(1,0,0) mynull.SetAbsPos(wc) mynull.SetName(null_name + " Point") doc.InsertObject(mynull) return def firerayat (start, direction, length, optemp_test): # startpoint, direction, length, object to colide collider = c4d.utils.GeRayCollider() collider.Init(optemp_test) #force cache rebuild with , True did_intersect = collider.Intersect(start, direction, length) #(start.GetAbsPos(), direction, length) if did_intersect: # creates null objects at the hitpos to visualize for debugging create_null(collider.GetNearestIntersection()["hitpos"], optemp_test.GetName(), optemp_test) return collider.GetIntersection(0)["distance"] else: return False """ Darter original def get_ray(start_obj, end_obj, goal): start = ~goal.GetMg() * start_obj.GetMg().off end = ~goal.GetMg() * end_obj.GetMg().off return {'ray_p' : start, 'ray_length' : (end - start).GetLength(), 'ray_dir' : (end - start).GetNormalized()} """ def get_ray(start_obj, end_obj, goal): #modified to accept vectors as start instead of object Global Mg start = ~goal.GetMg() * c4d.Vector(start_obj) end = ~goal.GetMg() * end_obj.GetMg().off return {'ray_p' : start, 'ray_length' : (end - start).GetLength(), 'ray_dir' : (end - start).GetNormalized()} def f2(seq): # order preserving checked = [] for e in seq: if e not in checked: checked.append(e) return checked def statusbar (counter, secondcounter): #c4d.StatusSetText ('%s - %s Objects are processed.' %(secondcounter, counter)) # very slow c4d.StatusSetBar(100*secondcounter/counter) #statusbar def put_on_layer (objlist, layer): nr = 0 while nr < len(objlist): objlist[nr].SetLayerObject(layer) objlist[nr][c4d.ID_BASEOBJECT_USECOLOR]=3 nr = nr+1 def delete_nulls (all_objects_list): # delet all Nulls exept my start this is just for debugging n = 0 while n < len(all_objects_list): optempdelete = all_objects_list[n] if optempdelete.GetType() == 5140 and not optempdelete.GetName() == "Start" and len(optempdelete.GetChildren())<1 : optempdelete.Remove() n = n+1 c4d.EventAdd() def main(): c4d.CallCommand(13957) # Konsole löschen now = c4d.GeGetTimer() # start stopwatch if GetActiveDocument(): doc = GetActiveDocument() if doc.GetFirstObject(): c4d.StatusSetSpin() op = doc.GetFirstObject() myobject = op all_objects = numberofobjects(op) # list off all objects counter = len(all_objects['all_objects_list']) all_objects_list = all_objects['all_objects_list'] poly_obj_list = all_objects['polygon_obj_list'] print "Polygon Objects: ", len(poly_obj_list) secondcounter = 0 c4d.StatusSetText ('%s Objects are processed.' %(counter)) opactive = None else: print "Error: No Objects" return False else: print "Error: No Document" return False delete_nulls (all_objects_list) # delet all Nulls exept my start this is just for debugging rayspline = doc.SearchObject("ray") if find_layer("Not hit"): layer_not_hit = find_layer("Not hit") else: layer_not_hit = create_layer("Not hit", c4d.Vector(0.5,0,0), True) if find_layer("Seen"): layer_seen = find_layer("Seen") else: layer_seen = create_layer("Seen", c4d.Vector(0,0.75,0), True) if find_layer("checked"): layer_checked = find_layer("checked") else: layer_checked = create_layer("checked", c4d.Vector(0,0,0.5), True) if doc.SearchObject("Start Point Cloud"): oldsphere = doc.SearchObject("Start Point Cloud") oldsphere.Remove() start_point_list = create_sphere(5, 500) # Subdivisions, Radius hit_list = [] never_hit = [] tested = [] print "Startpoint positions: ", len(start_point_list) print "-------------------------------------------------------------" c4d.EventAdd() si = 0 while si < len(start_point_list): statusbar(len(start_point_list), si) c4d.StatusSetText ('%s Objects and %s Ray Start Points are processed.' %(len(poly_obj_list), len(start_point_list))) nr_index = 0 while nr_index < len(poly_obj_list): optarget = poly_obj_list[nr_index] # print "Target: ",optarget.GetName() if optarget not in hit_list: tested.append(optarget) temp_op_tested_list = [] temp_distance_list = [] i = 0 while i < len(poly_obj_list): temp_op_tested_list.append(poly_obj_list[i]) if poly_obj_list[i] not in hit_list: ray = get_ray(start_point_list[si], optarget, poly_obj_list[i]) distance = firerayat(ray['ray_p'], ray['ray_dir'], ray['ray_length'], poly_obj_list[i]) temp_distance_list.append(distance) else: temp_distance_list.append(None) #print "Jumped: ", poly_obj_list[i].GetName() i = i+1 # print "temp_distance_list: ", temp_distance_list atuple = filter(None, tuple(temp_distance_list)) # print "Tuple: ", atuple if 0 != len(atuple): nearest_distance = min(x for x in atuple if x is not None) # attention min() is a generator and can only be called once for a list ! # Can this be done better - List Of List or similar? near_obj = temp_op_tested_list[temp_distance_list.index(nearest_distance)] print "Nearest Object: ", near_obj.GetName(), nearest_distance if near_obj not in hit_list: hit_list.append(near_obj) else: print "OpTarget was in hitlist - jumped: ", optarget.GetName() nr_index = nr_index + 1 si = si+1 # after loops never_hit = temp_op_tested_list + never_hit never_hit = f2(never_hit) # here or later have to watch memmory consumption !!! tested = f2(tested) for x in hit_list: if x in tested: tested.remove(x) for z in hit_list: if z in never_hit: never_hit.remove(z) # put on layer put_on_layer (hit_list, layer_seen) put_on_layer (never_hit, layer_not_hit) put_on_layer (tested, layer_checked) print "-------------------------------------------------------------" print "Tested count: ", len(tested) print "Hitlist count: ", len(hit_list) # print hit_list print "Never Hit: ", len(never_hit) print "Ray length: ", ray['ray_length'] print "Direction: ", ray['ray_dir'] rayspline.SetPoint(0, ~rayspline.GetMg() * -start_point_list[si-1] ) # si - 1 rayspline.SetPoint(1, ~(ray['ray_length'] * ray['ray_dir']) * rayspline.GetMg() ) # something wrong here ... rayspline.Message(c4d.MSG_UPDATE) print "-------------------------------------------------------------" print 'END OF SCRIPT - Duration: %s s ' %((c4d.GeGetTimer() - now)/1000) c4d.EventAdd() c4d.StatusClear() if __name__=='__main__': main()
__________________
R17 Visualize - Flickr Album - Website
 
Old 02-13-2013, 09:56 AM   #11
mogh
just hit render once more
 
mogh's Avatar
portfolio
Jan Weigand
Dipl. Industrial Designer
Fendt Traktors
Kaufbeuren, Germany
 
Join Date: Mar 2004
Posts: 626
Send a message via ICQ to mogh Send a message via MSN to mogh
Updated script Splines for debugging are generated automatically ...

otherwise still a lot of stuff wrong ...

Code:
import c4d from c4d import gui from c4d.documents import GetActiveDocument from c4d import utils # import math def GetNextObject(op): if not op: return if op.GetDown(): return op.GetDown() while op.GetUp() and not op.GetNext(): op = op.GetUp() return op.GetNext() def numberofobjects(op): all_list = list() poly_list = list() while op: all_list.append(op) if op.GetType() == 5100 and op.GetName() != "Start Point Cloud": # get all poly objects poly_list.append(op) op = GetNextObject(op) return {'all_objects_list' : all_list, 'polygon_obj_list' : poly_list } def find_layer(layername): root = doc.GetLayerObjectRoot() #Gets the layer manager myLayersList = root.GetChildren() foundname = False for lname in myLayersList: if lname.GetName() == str(layername): return lname def create_layer(name, color, display_seen): root = doc.GetLayerObjectRoot()#Gets the layer manager c4d.CallCommand(100004738) #create new layer mynewLayersList = root.GetChildren() # get the new list newlayer = mynewLayersList[-1] # get the last index of a list in this case layer newlayer[c4d.ID_LAYER_COLOR] = color # Sets layer color newlayer.SetName(name) # Sets layer name newlayer[c4d.ID_LAYER_VIEW] = display_seen #set layer view setting newlayer[c4d.ID_LAYER_RENDER] = display_seen #set layer render setting return newlayer # ray spline def create_spline_ray (goal, start, ray_dir, ray_length): spl = c4d.SplineObject(2,c4d.SPLINETYPE_LINEAR) #Create a 2pt. Bezier spline in memory only ~goal.GetMg() * spl.SetPoint(0, start * spl.GetMg() ) spl.SetPoint(1, ~spl.GetMg() * (ray_dir*ray_length)) # something wrong here ... ? spl.Message(c4d.MSG_POINTS_CHANGED) spl[c4d.ID_BASEOBJECT_USECOLOR] = True spl[c4d.ID_BASEOBJECT_COLOR] = c4d.Vector(1,1,0) spl.SetName("Ray to - " + goal.GetName()) doc.InsertObject(spl) c4d.EventAdd() def create_sphere(sub, radius): obj = c4d.BaseObject(c4d.Osphere) obj[c4d.PRIM_SPHERE_RAD] = radius obj[c4d.PRIM_SPHERE_SUB] = sub obj[c4d.PRIM_SPHERE_TYPE] = 4 obj[c4d.PRIM_SPHERE_PERFECT] = False obj.SetName("Start Point Cloud") # obj.SetMg(c4d.Matrix(c4d.Vector(1,1,1))) doc.InsertObject(obj) # Insert object in document obj.SetBit(c4d.BIT_ACTIVE) c4d.CallCommand(12236) # Grundobjekt konvertieren # obj.Message(c4d.MSG_UPDATE) newobj = doc.SearchObject("Start Point Cloud") create_display_tag(newobj) p_positions = newobj.GetAllPoints() """ for p in p_positions: print p_positions.index(p), p, obj.GetUpMg() p_positions[p_positions.index(p)] = obj.GetUpMg()*p # gloabl coordinates #print p_positions[p_positions.index(p)] """ # newobj.Remove() obj.DelBit(c4d.BIT_ACTIVE) c4d.EventAdd() # Send global event message return p_positions def create_display_tag(myobject): mytag = myobject.MakeTag(c4d.Tdisplay) mytag[c4d.DISPLAYTAG_AFFECT_DISPLAYMODE] = True mytag[c4d.DISPLAYTAG_SDISPLAYMODE] = 6 return # create nulls for visualizing the hitpos def create_null (coordinates, null_name, optemp_test): wc = optemp_test.GetMg() * coordinates mynull = c4d.BaseObject(c4d.Onull) mynull[c4d.ID_BASEOBJECT_USECOLOR] = True mynull[c4d.ID_BASEOBJECT_COLOR] = c4d.Vector(1,0,0) mynull.SetAbsPos(wc) mynull.SetName(null_name + " Point") doc.InsertObject(mynull) return def firerayat (start, direction, length, optemp_test): # startpoint, direction, length, object to colide collider = c4d.utils.GeRayCollider() collider.Init(optemp_test) #force cache rebuild with , True did_intersect = collider.Intersect(start, direction, length) #(start.GetAbsPos(), direction, length) if did_intersect: # creates null objects at the hitpos to visualize for debugging # create_null(collider.GetNearestIntersection()["hitpos"], optemp_test.GetName(), optemp_test) return collider.GetIntersection(0)["distance"] else: return False """ Darter original def get_ray(start_obj, end_obj, goal): start = ~goal.GetMg() * start_obj.GetMg().off end = ~goal.GetMg() * end_obj.GetMg().off return {'ray_p' : start, 'ray_length' : (end - start).GetLength(), 'ray_dir' : (end - start).GetNormalized()} """ def get_ray(start_obj, end_obj, goal): #modified to accept vectors as start instead of object Global Mg start = ~goal.GetMg() * c4d.Vector(start_obj) end = ~goal.GetMg() * end_obj.GetMg().off return {'ray_p' : start, 'ray_length' : (end - start).GetLength(), 'ray_dir' : (end - start).GetNormalized()} def f2(seq): # order preserving checked = [] for e in seq: if e not in checked: checked.append(e) return checked def statusbar (counter, secondcounter): #c4d.StatusSetText ('%s - %s Objects are processed.' %(secondcounter, counter)) # very slow c4d.StatusSetBar(100*secondcounter/counter) #statusbar def put_on_layer (objlist, layer): nr = 0 while nr < len(objlist): objlist[nr].SetLayerObject(layer) objlist[nr][c4d.ID_BASEOBJECT_USECOLOR]=3 nr = nr+1 def delete_nulls (all_objects_list): # delet all Nulls exept my start this is just for debugging n = 0 while n < len(all_objects_list): optempdelete = all_objects_list[n] if optempdelete.GetType() == 5140 and len(optempdelete.GetChildren()) == 0 or optempdelete.GetType() ==5101: optempdelete.Remove() n = n+1 c4d.EventAdd() def main(): c4d.CallCommand(13957) # Konsole löschen now = c4d.GeGetTimer() # start stopwatch if GetActiveDocument(): doc = GetActiveDocument() if doc.GetFirstObject(): c4d.StatusSetSpin() op = doc.GetFirstObject() myobject = op all_objects = numberofobjects(op) # list off all objects counter = len(all_objects['all_objects_list']) all_objects_list = all_objects['all_objects_list'] poly_obj_list = all_objects['polygon_obj_list'] print "Polygon Objects: ", len(poly_obj_list) secondcounter = 0 c4d.StatusSetText ('%s Objects are processed.' %(counter)) opactive = None else: print "Error: No Objects" return False else: print "Error: No Document" return False delete_nulls (all_objects_list) # delet all Nulls exept my start this is just for debugging rayspline = doc.SearchObject("ray") if find_layer("Not hit"): layer_not_hit = find_layer("Not hit") else: layer_not_hit = create_layer("Not hit", c4d.Vector(0.5,0,0), True) if find_layer("Seen"): layer_seen = find_layer("Seen") else: layer_seen = create_layer("Seen", c4d.Vector(0,0.75,0), True) if find_layer("checked"): layer_checked = find_layer("checked") else: layer_checked = create_layer("checked", c4d.Vector(0,0,0.5), True) if doc.SearchObject("Start Point Cloud"): oldsphere = doc.SearchObject("Start Point Cloud") oldsphere.Remove() start_point_list = create_sphere(5, 500) # Subdivisions, Radius hit_list = [] never_hit = [] tested = [] print "Startpoint positions: ", len(start_point_list) print "-------------------------------------------------------------" c4d.EventAdd() si = 0 while si < len(start_point_list): statusbar(len(start_point_list), si) c4d.StatusSetText ('%s Objects and %s Ray Start Points are processed.' %(len(poly_obj_list), len(start_point_list))) nr_index = 0 while nr_index < len(poly_obj_list): optarget = poly_obj_list[nr_index] print "Target: ",optarget.GetName() temp_op_tested_list = [] temp_distance_list = [] if optarget not in hit_list: tested.append(optarget) i = 0 while i < len(poly_obj_list): temp_op_tested_list.append(poly_obj_list[i]) if poly_obj_list[i] not in hit_list: ray = get_ray(start_point_list[si], optarget, poly_obj_list[i]) distance = firerayat(ray['ray_p'], ray['ray_dir'], ray['ray_length'], poly_obj_list[i]) create_spline_ray (poly_obj_list[i], start_point_list[si] , ray['ray_dir'], ray['ray_length']) # slow just for debugging temp_distance_list.append(distance) else: temp_distance_list.append(None) #print "Jumped: ", poly_obj_list[i].GetName() i = i+1 # print ray['ray_p'] , "Direction: ", ray['ray_dir'], " Ray length: ", ray['ray_length'] print "temp_distance_list: ", temp_distance_list atuple = filter(None, tuple(temp_distance_list)) # print "Tuple: ", i, atuple if 0 != len(atuple): nearest_distance = min(x for x in atuple if x is not None) # attention min() is a generator and can only be called once for a list ! # Can this be done better - List Of List or similar? near_obj = temp_op_tested_list[temp_distance_list.index(nearest_distance)] #print "Nearest Object: ", near_obj.GetName(), nearest_distance if near_obj not in hit_list: hit_list.append(near_obj) # else: print "OpTarget was in hitlist - jumped: ", optarget.GetName() nr_index = nr_index + 1 si = si+1 # after loops never_hit = temp_op_tested_list + never_hit never_hit = f2(never_hit) # here or later have to watch memmory consumption !!! tested = f2(tested) for x in hit_list: if x in tested: tested.remove(x) for z in hit_list: if z in never_hit: never_hit.remove(z) # put on layer put_on_layer (hit_list, layer_seen) put_on_layer (never_hit, layer_not_hit) put_on_layer (tested, layer_checked) print "-------------------------------------------------------------" print "Tested count: ", len(tested) print "Hitlist count: ", len(hit_list) # print hit_list print "Never Hit: ", len(never_hit) print "-------------------------------------------------------------" print 'END OF SCRIPT - Duration: %s s ' %((c4d.GeGetTimer() - now)/1000) c4d.EventAdd() c4d.StatusClear() if __name__=='__main__': main()
__________________
R17 Visualize - Flickr Album - Website
 
Old 02-14-2013, 08:44 PM   #12
pgrooff
PRO
 
Join Date: Oct 2003
Posts: 96
I'm still not sure what you want to achieve.
If it is just hitting an object with the ray collidion, have a look at my blog for a short tutorial on using the Ray Collision Xpresso node and python.
The node is used to get the polygon that was ‘hit’ by the Ray.
Python is then used to get the neighbor polygons.
All these polygons are added to the Polygon Selection Tag.
__________________
Please have a look at Plugins4D for plugin development and free plugins.
 
Old 02-14-2013, 09:06 PM   #13
mogh
just hit render once more
 
mogh's Avatar
portfolio
Jan Weigand
Dipl. Industrial Designer
Fendt Traktors
Kaufbeuren, Germany
 
Join Date: Mar 2004
Posts: 626
Send a message via ICQ to mogh Send a message via MSN to mogh
I am trying to build an advanced "manual" occlusion script.

http://forums.cgsociety.org/showthr...?f=47&t=1091288

I am hunting bugs for several days now and I've gone back to an earlier version just to understand more whats going on.

but as soon as i replace the target with all objects in a loop it gets weird ...

- First thing is to get my Globals and local Positions spot on its a mess at the moment I think.
- second is to know why it gets messy when i replace targets and goals and start points.

I have a hunch that my lists are not resetted the right way ...

anyway its to much to ask for you guys to solve my problems hence the script is quiet big already

but perhaps is there a "visual" explanation of Global and Local conversions ? :
kind regards mogh
__________________
R17 Visualize - Flickr Album - Website
 
Old 02-20-2013, 01:24 PM   #14
mogh
just hit render once more
 
mogh's Avatar
portfolio
Jan Weigand
Dipl. Industrial Designer
Fendt Traktors
Kaufbeuren, Germany
 
Join Date: Mar 2004
Posts: 626
Send a message via ICQ to mogh Send a message via MSN to mogh
Yay, first working version,

be carefull with number of polyobjects in your scene hence it chekcs every object against every object at least 12 times !

to control the rays increase the sphere subdiv in the script

regards mogh

Code:
import c4d from c4d import gui from c4d.documents import GetActiveDocument from c4d import utils # Version 0.18 def gime_time (time_start): milliseconds = c4d.GeGetTimer()-time_start hours,milliseconds = divmod(milliseconds, 3600000) minutes, milliseconds = divmod(milliseconds, 60000) seconds = float(milliseconds) / 1000 s = "%i:%02i:%06.3f" % (hours, minutes, seconds) return s def statusbar (counter, secondcounter): #c4d.StatusSetText ('%s - %s Objects are processed.' %(secondcounter, counter)) # very slow c4d.StatusSetBar(100*secondcounter/counter) #statusbar def GetNextObject(op): if not op: return if op.GetDown(): return op.GetDown() while op.GetUp() and not op.GetNext(): op = op.GetUp() return op.GetNext() def numberofobjects(op): all_list = list() poly_list = list() while op: all_list.append(op) if op.GetType() == 5100 and op.GetName() != "Start Point Cloud": # get all poly objects obj_atribute = [op, 0, 0] # object, #_tested, #_hitcount_nearest poly_list.append(obj_atribute) op = GetNextObject(op) return {'all_objects_list' : all_list, 'polygon_obj_list' : poly_list } # Layerstuff ---------------------------------------------------------------------------------- def find_layer(layername): root = doc.GetLayerObjectRoot() #Gets the layer manager myLayersList = root.GetChildren() foundname = False for lname in myLayersList: if lname.GetName() == str(layername): return lname def create_layer(name, color, display_seen): root = doc.GetLayerObjectRoot()#Gets the layer manager c4d.CallCommand(100004738) #create new layer mynewLayersList = root.GetChildren() # get the new list newlayer = mynewLayersList[-1] # get the last index of a list in this case layer newlayer[c4d.ID_LAYER_COLOR] = color # Sets layer color newlayer.SetName(name) # Sets layer name newlayer[c4d.ID_LAYER_VIEW] = display_seen #set layer view setting newlayer[c4d.ID_LAYER_RENDER] = display_seen #set layer render setting return newlayer def put_on_layer (objlist, layer): nr = 0 while nr < len(objlist): objlist[nr].SetLayerObject(layer) objlist[nr][c4d.ID_BASEOBJECT_USECOLOR]=3 nr = nr+1 # End Layerstuff ///////////////////////////////////////////////////////////////////////////// # ray spline --------------------------------------------------------------------------------- def create_spline_ray (optarget, start): spl = c4d.SplineObject(2,c4d.SPLINETYPE_LINEAR) #Create a 2pt. Bezier spline in memory only ~goal.GetMg() * spl.SetPoint(0, start * spl.GetMg() ) spl.SetPoint(1, optarget.GetMg().off * spl.GetMg() ) spl.Message(c4d.MSG_POINTS_CHANGED) spl[c4d.ID_BASEOBJECT_USECOLOR] = True spl[c4d.ID_BASEOBJECT_COLOR] = c4d.Vector(1,1,0) spl.SetName("Ray to - " + optarget.GetName()) doc.InsertObject(spl) c4d.EventAdd() # End ray spline ///////////////////////////////////////////////////////////////////////////// # sphere startpoints ------------------------------------------------------------------------- def create_sphere(sub, radius, cord_vec, delete_me): obj = c4d.BaseObject(c4d.Osphere) obj[c4d.PRIM_SPHERE_RAD] = radius obj[c4d.PRIM_SPHERE_SUB] = sub obj[c4d.PRIM_SPHERE_TYPE] = 4 obj[c4d.PRIM_SPHERE_PERFECT] = False obj.SetName("Start Point Cloud") obj.SetMg(c4d.Matrix(cord_vec)) obj.Message(c4d.MSG_POINTS_CHANGED) doc.InsertObject(obj) # Insert object in document obj.SetBit(c4d.BIT_ACTIVE) c4d.CallCommand(12236) # Grundobjekt konvertieren # obj.Message(c4d.MSG_UPDATE) newobj = doc.SearchObject("Start Point Cloud") if delete_me != True: create_display_tag(newobj) p_positions = newobj.GetAllPoints() new_list = [] for p in p_positions: # print p_positions.index(p), p, obj.GetMg() new_list.append(obj.GetMg() * p) # gloabl coordinates #print p_positions[p_positions.index(p)] if delete_me == True: newobj.Remove() obj.DelBit(c4d.BIT_ACTIVE) c4d.EventAdd() # Send global event message return new_list def create_display_tag(myobject): mytag = myobject.MakeTag(c4d.Tdisplay) mytag[c4d.DISPLAYTAG_AFFECT_DISPLAYMODE] = True mytag[c4d.DISPLAYTAG_SDISPLAYMODE] = 6 return # End sphere startpoints ////////////////////////////////////////////////////////////////////// # create nulls for visualizing the hitpos ----------------------------------------------------- def create_null (coordinates, null_name, optemp_test): wc = optemp_test.GetMg() * coordinates mynull = c4d.BaseObject(c4d.Onull) mynull[c4d.ID_BASEOBJECT_USECOLOR] = True mynull[c4d.ID_BASEOBJECT_COLOR] = c4d.Vector(1,0,0) mynull.SetAbsPos(wc) mynull.SetName(null_name + " Point") doc.InsertObject(mynull) return def delete_nulls (all_objects_list): # delet all Nulls exept my start this is just for debugging n = 0 while n < len(all_objects_list): optempdelete = all_objects_list[n] if optempdelete.GetType() == 5140 and len(optempdelete.GetChildren()) == 0 or optempdelete.GetType() == 5101: optempdelete.Remove() n = n+1 c4d.EventAdd() # End create nulls /////////////////////////////////////////////////////////////////////////// def f2(seq): # order preserving checked = [] for e in seq: if e not in checked: checked.append(e) return checked # Ray stuff and nearest obj ------------------------------------------------------------------------------------- """ Darter original def get_ray(start_obj, end_obj, goal): start = ~goal.GetMg() * start_obj.GetMg().off end = ~goal.GetMg() * end_obj.GetMg().off return {'ray_p' : start, 'ray_length' : (end - start).GetLength(), 'ray_dir' : (end - start).GetNormalized()} """ def get_ray(start_obj, end_obj, goal): #modified to accept vectors as start instead of object Global Mg start = ~goal.GetMg() * c4d.Vector(start_obj) end = ~goal.GetMg() * end_obj.GetMg().off return {'ray_p' : start, 'ray_length' : (end - start).GetLength(), 'ray_dir' : (end - start).GetNormalized()} def firerayat (start, direction, length, optemp_test): # startpoint, direction, length, object to colide collider = c4d.utils.GeRayCollider() collider.Init(optemp_test) #force cache rebuild with , True did_intersect = collider.Intersect(start, direction, length) #(start.GetAbsPos(), direction, length) if did_intersect: create_null(collider.GetNearestIntersection()["hitpos"], optemp_test.GetName(), optemp_test) #debugging return collider.GetNearestIntersection()["distance"] #return collider.GetIntersection(0)["distance"] else: return None def get_nearest_obj_in_list (temp_op_distance_list): temp_op_distance_list.sort(key=lambda x: x[1]) #print temp_op_distance_list[0][0], temp_op_distance_list[0][1] if len(temp_op_distance_list) != 0 and temp_op_distance_list[0][1] != None: return temp_op_distance_list[0][0] def get_nearest_obj (start_point, target, obj_list, jump): #jump is bullshit we can't jump anything hence it could be in the line of sight temp_op_distance_list = [] #Reset for obj_rows in obj_list: opgoal = obj_rows[0] # object, #_tested, #_counter_nearest ray = get_ray( start_point, target, opgoal ) distance = firerayat(ray['ray_p'], ray['ray_dir'], ray['ray_length'], opgoal) if distance != None: #print "Distance: ", distance, " - ", opgoal.GetName(), start_point temp_op_distance_list.append( [opgoal, distance] ) near_obj = get_nearest_obj_in_list(temp_op_distance_list) for i, row in enumerate(obj_list): if near_obj in row: print "Found Near Object at Row Index: ", i, " Column: ", row.index(near_obj), " obj Name: ", obj_list[i][0].GetName() obj_list[i][2] = obj_list[i][2] + 1 # increment the hitcounter # End ray ////////////////////////////////////////////////////////////////////// def layer_init (l_name, color, displayseen): if find_layer(l_name): x_layer = find_layer(l_name) else: x_layer = create_layer(l_name, color, displayseen) return x_layer # Main ---------------------------------------------------------------------------------------- def main(): c4d.CallCommand(13957) # Konsole löschen time_start = c4d.GeGetTimer() # start stopwatch if GetActiveDocument(): doc = GetActiveDocument() if doc.GetFirstObject(): c4d.StatusSetSpin() op = doc.GetFirstObject() all_objects = numberofobjects(op) # list off all objects counter = len(all_objects['all_objects_list']) all_objects_list = all_objects['all_objects_list'] poly_obj_list = all_objects['polygon_obj_list'] c4d.StatusSetText ('%s Objects are processed.' %(counter)) else: print "Error: No Objects" return False else: print "Error: No Document" return False # delete_nulls (all_objects_list) # delete all Nulls exept my start this is just for debugging layer_not_hit = layer_init ("Not hit", c4d.Vector(0.5,0,0), True) # True layer seen display option layer_seen = layer_init ("Seen", c4d.Vector(0,0.25,0), True) layer_seen_def = layer_init ("Seen more than once", c4d.Vector(0.5,0.75,0), True) layer_checked = layer_init ("checked", c4d.Vector(0,0,0.75), True) if doc.SearchObject("Start Point Cloud"): oldsphere = doc.SearchObject("Start Point Cloud") oldsphere.Remove() if doc.SearchObject("Manual_Target_01"): manual_target = doc.SearchObject("Manual_Target_01") else: manual_target = 0 start_point_list = create_sphere(5, 500, c4d.Vector(100,1,1), True) # Subdivisions, Radius, c4d.vector, deleteme=True False hit_list = [] never_hit = [] tested = [] hit_list_definatly = [] jump = 3 # if an object was hit 2 times jump it for ray colision print "Polygon Objects: ", len(poly_obj_list) print "Startpoint positions: ", len(start_point_list) print "-------------------------------------------------------------" count_a = 0 count_b = 0 count_c = 0 si = 0 for start_cord in start_point_list: #start_cord = start_point_list[5] #manual for debugging c4d.StatusSetText ('%s Objects and %s Ray Start Points are processed.' %(len(poly_obj_list), len(start_point_list))) count_a += 1 if manual_target == 0: for row_obj in poly_obj_list: statusbar(len(poly_obj_list)*len(start_point_list) , count_b) count_b += 1 optarget = row_obj[0] # Target for Ray - may also be a coordinate in the future row_obj[1] += 1 # targetcounter in list of list +1 # if optarget.GetName() == "should not": create_spline_ray (optarget, start_cord) # slow just for debugging # this is the main function which dows the magic get_nearest_obj( start_cord, optarget, poly_obj_list, jump) # startpoint, target, objlist, jump # End magic ////////////////////////////////////////////////////////////////////// else: print "Manual Target Used" statusbar(len(poly_obj_list)*len(start_point_list) , count_b) count_b += 1 optarget = manual_target # Target for Ray - may also be a coordinate in the future create_spline_ray (optarget, start_cord) # slow just for debugging # this is the main function which dows the magic get_nearest_obj( start_cord, optarget, poly_obj_list, jump) # startpoint, target, objlist, jump # End magic ////////////////////////////////////////////////////////////////////// # after loops print "--------------" for row in poly_obj_list: print "Tested: ", row[1]," - Hitcounter: ", row[2], " - Name: ", row[0].GetName() if row[1] == 0: tested.append(row[0]) # append the object to the tested list this is not used at the moment just stored if row[2] == 0: never_hit.append(row[0]) else: if row[2] == jump: hit_list.append(row[0]) if row[2] >= jump: hit_list_definatly.append(row[0]) put_on_layer (hit_list_definatly, layer_seen_def) put_on_layer (hit_list, layer_seen) put_on_layer (never_hit, layer_not_hit) #put_on_layer (tested, layer_checked) print "-------------------------------------------------------------" print "Never Tested count: ", len(tested) print "Hitlist count: ", len(hit_list) print "Hit more than %s times: " %jump, len(hit_list_definatly) print "Never Hit: ", len(never_hit) print "---------------------------------------------------------------------" print 'END OF SCRIPT - Duration (H:MM:SS:ms): %s' %(gime_time(time_start)) c4d.EventAdd() c4d.StatusClear() if __name__=='__main__': main()
__________________
R17 Visualize - Flickr Album - Website
 
Old 02-20-2013, 01:24 PM   #15
CGTalk Moderation
Lord of the posts
CGTalk Forum Leader
 
Join Date: Sep 2003
Posts: 1,066,480
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


Thread Tools Search this Thread
Search this Thread:

Advanced Search
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

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
CGSociety
Society of Digital Artists
www.cgsociety.org

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

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


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