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.