I'm using a tooldata plugin and was originally trying to get the polygon data from a generator/objectdata object. That doesn't work because even though it's classed as a polygon object, no polygon data is available to grab from outside. Always returns as None. So I thought I'd just get the hit position and then reference that with the object itself. Only problem is, can't do that either. I can get pickobject to give me the generator object but no more info, no hit position, z-depth, nothing. GeRayCollider is the same story.
None of the ViewportSelect methods can get me this info either.
c4d.utils.ViewportSelect.PickObject() is supposed to return a Z value but doesn't.
could you please follow our forum guidelines when posting a question, using tags and mark you thread as a questions can help us to answer your questions faster.
Generator are not polygon objects, they store virtual object in their cache. It is also explained on the python documentation
That's pretty logical to me that you can't have any information from the generator.
What kind of information are you trying to retrieve ?
Ah apologies, I will make sure to follow the guidelines in future.
So I'm building a python objectdata plugin that will create geometry but I want to add more geometry to it with a tooldata plugin by brushing over the geometry that has already been created, the tooldata will just tell the objectdata to create the geometry though. The object data plugin will keep track of all geometry in order for other tooldata plugins to act on that geometry.
To put the new geo in the correct position though, I would need to know on what coordinate of the already generated geometry I would be hitting with the mouse, ideally I'd like access to the normal of the hitpoint too. Is there any way to detect a mouseover event on a virtual object?
As Manuel stated, you'll need to get the object's cache (baseObjectPtr->GetCache()). If you need the exact projected position of your mouse cursor on the polygon geometry, my first idea would be to use class GeRayCollider to shoot rays from your camera through the mouse cursor onto the geometry. Since you get a BaseDraw* in ToolData::MouseInput() you have all the necessary functions to transform mouse coordinates to world space.
using github example will help you to build your tool.
using the liquid paint plugin as a base, using the script example to iterate over caches where you can get the function DeformedPolygonCacheIterator
Int the function GetCursorInfo you have to retrieve the object the mouse is over, this can be done with the fuction c4d.utils.ViewportSelect.PickObject and GetPixelInfoPolygon
def GetCursorInfo(self, doc, data, bd, x, y, bc):
xPos = int(x)
yPos = int(y)
vpSelect = c4d.utils.ViewportSelect()
rad = 20
flags = c4d.VIEWPORT_PICK_FLAGS_NONE
# Retrieve the object that are hovered by the mouse
objectsList = c4d.utils.ViewportSelect.PickObject(bd, doc, xPos, yPos, rad, flags)
# Retrieve the frame information, we need the height and width information to initialize the ViewportSelect object.
frame = bd.GetFrame()
width = right - left + 1
height = bottom - top + 1
# Retrieve the object as PolygonObject
polygonObjectList = list()
for op in objectsList:
for cache in self.DeformedPolygonCacheIterator(op):
if len(polygonObjectList) < 1:
# Init the viewportSelect object
if not vpSelect.Init(width, height, bd, polygonObjectList, c4d.Mpolyedgepoint, True, c4d.VIEWPORTSELECTFLAGS_IGNORE_HIDDEN_SEL):
# Retrieve the polygon information
infopolygon = vpSelect.GetPixelInfoPolygon(xPos, yPos)
if not infopolygon:
i = infopolygon["i"] # int
op = infopolygon["op"] # c4d.BaseObject
z = infopolygon["z"] # float
# Build the array of the polygon vertices in world coordinates
cpoly = op.GetPolygon(i)
opmg = op.GetMg()
self.pointList = list()
if not cpoly.IsTriangle():
# Transform the local coordinates to world coordinates.
self.pointList = [opmg * p for p in self.pointList]
# Update the view.
c4d.DrawViews(c4d.DA_ONLY_ACTIVE_VIEW | c4d.DA_NO_THREAD | c4d.DA_NO_ANIMATION)
# If the cursor has left a user area, simply return True
if bc.GetId() == c4d.BFM_CURSORINFO_REMOVE:
# Sets the BubbleHelp string and cursor.
@m_magalhaes Manuel you hero! That was it! DeformedPolygonCacheIterator was the key! Thank you so much!