Frame Selected Object
-
On 09/05/2014 at 15:06, xxxxxxxx wrote:
I'm trying to render the active object isolated from all other objects of the document.
To do so, from inside my plugin, I created a new document, created a clone of the intended object and inserted it in the new document. Then I performed a render of that object and finally, get rid of that document.
It all works fine, except that I can't seem to perform a "Frame Selected Object" on the object that is inside the new document. When I run that command, the current object, still in my current object gets framed.
I'm using this code:doc = documents.GetActiveDocument()
new_doc=c4d.documents.BaseDocument()
rd = new_doc.GetActiveRenderData().GetData()
new_tree=node.GetClone()
new_doc.InsertObject(new_tree)
xres = 128
yres = 128
bmp = bitmaps.BaseBitmap()
bmp.Init(x=xres, y=yres, depth=24)
rd[c4d.RDATA_XRES]=xres
rd[c4d.RDATA_YRES]=yres
new_doc.SetSelection(new_tree,c4d.SELECTION_NEW)
c4d.CallCommand(12151) # Frame Selected Objects
res = documents.RenderDocument(new_doc, rd, bmp, c4d.RENDERFLAGS_EXTERNAL)
if res==c4d.RENDERRESULT_OK:
bitmaps.ShowBitmap(bmp)
new_doc.Flush()How can I frame just the cloned object, inside the new document?
-
On 10/05/2014 at 00:05, xxxxxxxx wrote:
How do you think the CallCommand would know that it should use your
new document? It operates always on the active scene only.-Niklas
-
On 10/05/2014 at 01:11, xxxxxxxx wrote:
I thought it would operate like how you say, but I tried the "shot in the dark" of selecting the newly inserted object and hopped that it would affect the last selected object
So, it must be made by hand, adjusting the virtual camera of the new document?
Does anyone now how to calculate the placement and orientation of the camera to frame an object? -
On 10/05/2014 at 03:15, xxxxxxxx wrote:
You didn't make the new_doc the current document.
Insert it and make it the active document. -
On 10/05/2014 at 03:54, xxxxxxxx wrote:
Thank you, Niklas. It worked!!!
However, the object is not being framed correctly.
My code is this:doc = documents.GetActiveDocument()
new_doc=c4d.documents.BaseDocument()
rd = new_doc.GetActiveRenderData()
rdc = rd.GetData()
new_tree=node.GetClone()
new_doc.InsertObject(new_tree)
xres = 256
yres = 256
bmp = bitmaps.BaseBitmap()
bmp.Init(x=xres, y=yres, depth=24)
rdc[c4d.RDATA_XRES]=xres
rdc[c4d.RDATA_YRES]=yres
rd.SetData(rdc)
c4d.documents.SetActiveDocument(new_doc)
new_doc.SetActiveRenderData(rd)
c4d.EventAdd(c4d.EVENT_FORCEREDRAW)
new_doc.SetSelection(new_tree,c4d.SELECTION_NEW)
c4d.CallCommand(12151) # Frame Selected Objects
res = documents.RenderDocument(new_doc, rdc, bmp, c4d.RENDERFLAGS_EXTERNAL)
c4d.documents.SetActiveDocument(doc)
if res==c4d.RENDERRESULT_OK:
bitmaps.ShowBitmap(bmp)
new_doc.Flush()The render shows a clipped object
-
On 10/05/2014 at 05:33, xxxxxxxx wrote:
Already tried with:
c4d.CallCommand(12148) # Frame Geometry
and with
c4d.CallCommand(12288) # Frame All
To no avail
-
On 10/05/2014 at 11:29, xxxxxxxx wrote:
Ok, never mind. I created my own framing code. It works for what I need.
-
On 11/05/2014 at 04:26, xxxxxxxx wrote:
Hi Rui,
# Copyright (c) 2014 Niklas Rosenstein # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. r""" This script shows how to frame the current object and then render it into a 256x256 image without loosing information such as the object's materials. Absolutely non-destructive and memory-optimized. Changelog: v 0.1.0 (May 11, 2014) Initial version """ import c4d class Remember(object) : r""" Remembers the hierarchy position of a node and can restore it at a later time. A ``root_routine`` is required when the node was the first and only node in the list. """ def \__init\_\_(self, node) : super(Remember, self).\__init\_\_() self.parent = node.GetUp() self.pred = node.GetPred() def restore(self, node, root_routine) : node.Remove() if self.pred: node.InsertAfter(self.pred) elif self.parent: node.InsertUnder(self.parent) else: root_routine(node) class DocumentContext(object) : r""" Context manager for a temporary document that will be inserted when entering the context and \*killed\* when leaving the context. The document can and must not be used after the context was left. Inside the context, the document is inserted and active. """ def \__init\_\_(self, doc=None) : if not doc: doc = c4d.documents.BaseDocument() elif not isinstance(doc, c4d.documents.BaseDocument) : raise TypeError('expected BaseDocument') super(DocumentContext, self).\__init\_\_() self.doc = doc def \__enter\_\_(self) : c4d.documents.InsertBaseDocument(self.doc) c4d.documents.SetActiveDocument(self.doc) return self.doc def \__exit\_\_(self, exc_type, exc_value, exc_tb) : c4d.documents.KillDocument(self.doc) def render_object(op, width, height) : r""" Renders the object \*op\* with the specified resolution. Returns the resulting :class:`c4d.bitmaps.BaseBitmap`. It tries to keep the memory overhead at a minimum by stripping down op's document before cloning it. """ doc = op.GetDocument() if not doc: raise ValueError('op is not in a document') # Remember the original position of \*op\* in the hierarchy and # remove it from the tree. location = Remember(op) op.Remove() # Put all the objects in the document into a Null-Object that # we will keep separate. root_null = c4d.BaseObject(c4d.Onull) for obj in reversed(doc.GetObjects()) : obj.Remove() obj.InsertUnder(root_null) # Insert it into the document again. Then we clone it to get a # document with all the materials that the object referenced. doc.InsertObject(op) new_doc = doc.GetClone(c4d.COPYFLAGS_0) # Restore the structure of the original document. for obj in reversed(root_null.GetChildren()) : obj.Remove() doc.InsertObject(obj) root_null.Remove() location.restore(op, root_routine=doc.InsertObject) # Frame the object and render the new document. with DocumentContext(new_doc) : new_doc.SetActiveObject(new_doc.GetFirstObject()) force_redraw() # Redraw is required to create the Geometry c4d.CallCommand(12151) # Frame Selected Objects return render_document(new_doc, width, height) def render_document(doc, width, height, depth=24) : r""" Renders \*doc\* with the specified width and height. """ bmp = c4d.bitmaps.BaseBitmap() bmp.Init(x=width, y=width, depth=depth) rdc = doc.GetActiveRenderData().GetData() rdc[c4d.RDATA_XRES] = width rdc[c4d.RDATA_YRES] = height c4d.documents.RenderDocument(doc, rdc, bmp, c4d.RENDERFLAGS_EXTERNAL) return bmp def force_redraw() : r""" Force a redraw for the current document. """ flags = c4d.DRAWFLAGS_NO_THREAD | c4d.DRAWFLAGS_FORCEFULLREDRAW c4d.DrawViews(flags) def main() : if not op: c4d.gui.MessageDialog("Please select one object.") return bmp = render_object(op, 256, 256) c4d.bitmaps.ShowBitmap(bmp) main()
This should help you.
-Niklas -
On 11/05/2014 at 06:49, xxxxxxxx wrote:
Thank you Niklas. I learned a lot with this code.