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