How to do that the genertaed object fill the viewport and be centered, because the object is too large.
I tried to use the c4d.CallCommand(12148) inside the GetVirtualObjects() function but this doesn't work. its work only if I use it inside Message() function.
is there a possibility to do that using python
at least for me it is really hard to answer your question in the current form.
Modifying the active camera (letting an object fill the view) is quite an unusual thing for both a Python Generator Object and a ObjectData plugin to do. You might want to reconsider your approach. Also worth mentioning is that ObjectData.GetVirtualObjects() is executed in a threaded context, in which it is forbidden or disencouraged to modify the scene or add events. Invoking the 'center in view'-command does both (it modifies the editor camera object), so unexpected behavior is in this case actually to be expected
To get better help you should post your code and describe your problems more in detail.
I created the following example just to demonstrate my issue:
def Init(self, op):
self.InitAttr(op, float, [c4d.MYCUBE_OBJECT_WIDTH])
self.InitAttr(op, float, [c4d.MYCUBE_OBJECT_HEIGHT])
self.InitAttr(op, float, [c4d.MYCUBE_OBJECT_DEPTH])
data = op.GetDataInstance()
def GetVirtualObjects(self, op, hierarchyhelp):
width = op[c4d.MYCUBE_OBJECT_WIDTH]
height = op[c4d.MYCUBE_OBJECT_HEIGHT]
depth = op[c4d.MYCUBE_OBJECT_DEPTH]
cube = c4d.BaseObject(c4d.Ocube)
cube[c4d.PRIM_CUBE_LEN, c4d.VECTOR_X] = width
cube[c4d.PRIM_CUBE_LEN, c4d.VECTOR_Y] = height
cube[c4d.PRIM_CUBE_LEN, c4d.VECTOR_Z] = depth
And here is an screenshot for the given result :
The object is too large and it cut off in the viewport, and my object must be with the given dimensions above
while what you are doing is much clearer now, I still do not really get your problem An ObjectData plugin that implements GetVirtualObjects is not really supposed to modify the scene camera. Therefor I am a bit hesitant to tell you ways how you could circumvent the threaded context of GVO.
Just consider an user has three of your MyCube objects in his/her scene and has animated a parameter in each of these objects. When he/she starts the scene playback GVO will be invoked for each object at least once per frame. If you had some sort of camera logic attached to the execution of your GVO, the scene camera would wildly jump from object to object for each frame and the user would not be able to interact with the scene anymore.
If you really want to have some sort of "frame this object"-logic attached to your object, I would propose adding a button to your description resource and then frame the object when the user presses that button.
My object is limited to only one Object instance by document, (is not possible to open more than one object in current document). It is a studio light kit that will contain a lot of objects. I had thought about adding button to do that.
Anyway, thank you very much for your help. I will probably adding button to do that.
As Zipit said, this is not the right place to trigger event or change the scene.
What I would like to know is if it's a "once shot" or "always".
If it's one shot, you could Create a script or a commandData that will add your generator to the scene and take care of changing the camera to Frame it. This is allowed.
If it's "always"
As I understand, you are going to create a Cube (we know the size) and put object Inside it ?
So you can move your cube backward (in camera space). You just have to check if your 8 points are in the frame.
That remember a bit this post. You will find code and information to check if your object is framed..
Once again, don't update the scene or move the camera in a generator.
hope that helped.
it's a "once shot" I would like to execute this command only on the first object open. in the case if the object is saved and reopened the command should not be re-executed. And also I don't want to move the object out of the world center.
No problem, I will just add a button to my description resource and run the command c4d.CallCommand(12151) # Frame Selected Objects
if you only want to frame the object on instantiation and also want to restrict the user to only being able to create one of your objects (which you cannot really do either in a safe way from within an ObjectData plugin), then the solution proposed by @m_magalhaes - writing a CommandData wrapper - is probably the best solution, as it can do both easily.
We already talked on this thread about how to limit the number of object in a scene.
(it's cool to see tools coming to life)
So if you just want to frame the object from time to time, and still want to have that in your interface, i think the button is probably the best solution.
without any news, i'll pass this thread to solved.
ok Thank you. I have used the solution that I have mentioned above.