Get visible objects from viewport in commandline
-
I think problem is C4d is not initialized BaseDraw from Commandline because BaseDraw, PickObject, GetFrame didn't in Gui console. I tried to take BaseDraw.GetSafeFrame () and got 0,0,0,0. Also tried to run the script from Gui, I was able to get GetFrame () when I did BaseDraw.InitializeView (self, doc, cam, editorsv) (but still not the same as the console in Gui). In fact PickObject, GetFrame work well in Gui console.
-
I am writing a script that runs the C4d command line ("Commandline.exe" - nogui, etc.) and works in it.The Gui console is the console that is called with shift+F10 in c4d.
-
hi,
it's not really clear, what is your final goal ?
Cheers,
Manuel -
@m_magalhaes
Hi, I want to get an array of visible objects from "camera view", via cinema 4d commandline.exe if possible -
Code example:
import os import sys import c4d def PluginMessage(_id, data): if _id == c4d.C4DPL_COMMANDLINEARGS: print sys.argv walker() return True return False def walker(step_x=5,step_y=5): doc = c4d.documents.GetActiveDocument() print "Document: {}".format(doc) bd = doc.GetRenderBaseDraw() print "BaseDraw: {}".format(bd) safeframe = bd.GetSafeFrame() print "SafeFrame: {}".format(safeframe) arr_o = [] for y in range(safeframe['cl'],safeframe['cr'],step_y): for x in range(safeframe['ct'],safeframe['cb'],step_x): o = c4d.utils.ViewportSelect.PickObject(bd, doc, x, y, rad=1, flags=c4d.VIEWPORT_PICK_FLAGS_OGL_ONLY_TOPMOST_WITH_OBJ | c4d.VIEWPORT_PICK_FLAGS_OGL_ONLY_VISIBLE) if o: try: arr_o.append(o[0]) except IndexError as e: print(e) print "Array of objects: {}".format(arr_o) return arr_o
Output:
['C:\\Users\\Administrator\\Documents\\1.c4d', '-nogui'] Document: <c4d.documents.BaseDocument object called '' with ID 110059 at 0x00000 08ABA5CC3B0> BaseDraw: <c4d.BaseDraw object called 'Perspective' with ID 110305 at 0x0000008A BA5CC3F0> SafeFrame: {'cr': 0, 'ct': 0, 'cb': 0, 'cl': 0} Array of objects: []
Cmd command:
C:\Program Files\MAXON\Cinema 4D R20>Commandline.exe "C:\Users\Administrator\Documents\1.c4d" -nogui
-
Hi,
the
BaseDraw
is probably not being properly initialised due to being hosted by a GUI-less environment. I also would be surprised, ifViewportSelect
would work properly in this environment. You could either ray-intersection test all objects in the scene by firing rays (withGeRayCollider
) through a grid on the view plane of the camera - similarly to what you are doing in your script. But that would be slow and prone to False Negatives (i.e. stepping over very small objects) like that grid approach is in general. The advantage of that approach is that it will produce no False Positives unlike the following approach.The much faster and more common way would be to intersection test the bounding box of each object with the view frustum of the camera. One common algorithm is the Axis-Aligned-Bounding-Box (AABB) algorithm which comes in many flavours. There is a nice educational paper on the topic of cone/box intersections by David Eberly, but if you google for AABB intersection, you will find many more.
Cheers,
zipit -
@zipit , Hi.
The methods you suggested will not work for me, since bbox has an error(example: if the bbox of a sphere is included in one corner of the frame, but the sphere itself does not fall into our frame, the source masive will have a sphere object), and GeRayCollider because It does not return objects.Maybe you know how to initialize ViewportSelect to make It work, maybe there is the same method as loading caches for objects in Commandline.exe
-
Hi,
I am aware that AABB frustum culling will produce False Positives, that is why I mentioned it However, I am not quite sure, if you are aware that your method, either by manually ray-casting, like I proposed, or by using
ViewPortSelect
is subject to False Negatives, i.e. can report misses where it should report hits. That hapens when your ray-casting grid is to broad.Also: The ray-casting method proposed be me is verly likely very close to what
ViewPortSelect
is doing internally. Note thatGeRayCollider
has a glancing hit functionality, which would let you compensate for the grid approach weakness, i.e. emulate the radius argument ofViewPortSelect
.Finally, while technically you can instantiate a
BaseDraw
from scratch, you cannot specify the screen dimensions of its super classBaseView
, nor are you able to modify these attributes on an existing instance. So when Cinema gives you only a "dummy"BaseDraw
with the zero vector for its dimensions, you are cannot useViewPortSelect
since it relies on aBaseDraw
for its inputs.Cheers,
zipit -
hi,
the problem isn't coming from the fact that there's no GUI but that c4d didn't finished to initialized. Even with the UI, it's the same problem.
I'm trying to find a place where you could/catch the right message but until now, all the solution have failed.But i still have one solution or two on my pocket.
Cheers,
Manuel -
Hi,@m_magalhaes
I tried all the messages, and did not find where this could work. Could you tell me the right solution? -
hi,
I tried creating a CommandData that you could be triggered with a parameter --> not working
I tried creating a ObjectData that could react toMSG_DOCUMENTINFO
in itsMessage
function when the document is loaded --> not working
I tried when the program is closing --> not workingBased on my knowledge, there's no solution for your issue.
Cheers,
Manuel