def render(outputfile,scene=None,camera=None,zoom=False,width=400,height=300,background=(1.0,1.0,1.0)): """render(outputfile,scene=None,camera=None,zoom=False,width=400,height=300,background=(1.0,1.0,1.0)): Renders a PNG image of given width and height and background color from the given coin scene, using the given coin camera (ortho or perspective). If zoom is True the camera will be resized to fit all objects. The outputfile must be a file path to save a png image.""" # On Linux, the X server must have indirect rendering enabled in order to be able to do offline # PNG rendering. Unfortunately, this is turned off by default on most recent distros. The easiest # way I found is to edit (or create if inexistant) /etc/X11/xorg.conf and add this: # # Section "ServerFlags" # Option "AllowIndirectGLX" "on" # Option "IndirectGLX" "on" # EndSection # # But there are other ways, google of GLX indirect rendering if isinstance(camera,str): camera = getCoinCamera(camera) print("Starting offline renderer") # build an offline scene root separator root = coin.SoSeparator() # add one light (mandatory) light = coin.SoDirectionalLight() root.addChild(light) if not camera: # create a default camera if none was given camera = coin.SoPerspectiveCamera() cameraRotation = coin.SbRotation.identity() cameraRotation *= coin.SbRotation(coin.SbVec3f(1,0,0),-0.4) cameraRotation *= coin.SbRotation(coin.SbVec3f(0,1,0), 0.4) camera.orientation = cameraRotation # make sure all objects get in the view later zoom = True root.addChild(camera) if scene: root.addChild(scene) else: # no scene was given, add a simple cube cube = coin.SoCube() root.addChild(cube) vpRegion = coin.SbViewportRegion(width,height) if zoom: camera.viewAll(root,vpRegion) print("Creating viewport") offscreenRenderer = coin.SoOffscreenRenderer(vpRegion) offscreenRenderer.setBackgroundColor(coin.SbColor(background[0],background[1],background[2])) print("Ready to render") # ref ensures that the node will not be garbage-collected during rendering root.ref() ok = offscreenRenderer.render(root) root.unref() if ok: offscreenRenderer.writeToFile(outputfile,"PNG") print("Rendering",outputfile,"done") else: print("Error rendering image")
def get_text_size(self, vobj): """Return the bounding box of the text element.""" if vobj.DisplayMode == "3D text": node = self.node3dtxt else: node = self.node2dtxt region = coin.SbViewportRegion() action = coin.SoGetBoundingBoxAction(region) node.getBoundingBox(action) return action.getBoundingBox().getSize().getValue()
def makeSnapshotWithoutGui(): from pivy import coin # create a test geometry and create an IV representation as string box = Part.makeCone(10, 8, 10) iv = box.writeInventor() # load it into a buffer inp = coin.SoInput() try: inp.setBuffer(iv) except Exception: tempPath = tempfile.gettempdir() fileName = tempPath + os.sep + "cone.iv" file = open(fileName, "w") file.write(iv) file.close() inp.openFile(fileName) # and create a scenegraph data = coin.SoDB.readAll(inp) base = coin.SoBaseColor() base.rgb.setValue(0.6, 0.7, 1.0) data.insertChild(base, 0) # add light and camera so that the rendered geometry is visible root = coin.SoSeparator() light = coin.SoDirectionalLight() cam = coin.SoOrthographicCamera() root.addChild(cam) root.addChild(light) root.addChild(data) # do the rendering now axo = coin.SbRotation(-0.353553, -0.146447, -0.353553, -0.853553) viewport = coin.SbViewportRegion(400, 400) cam.orientation.setValue(axo) cam.viewAll(root, viewport) off = coin.SoOffscreenRenderer(viewport) root.ref() off.render(root) root.unref() # export the image, PS is always available off.writeToPostScript("crystal.ps") # Other formats are only available if simage package is installed if off.isWriteSupported("PNG"): print("Save as PNG") off.writeToFile("crystal.png", "PNG")
def make_snapshot(input_file, output_file, size=48): from pivy import coin ext = os.path.splitext(input_file)[1][1:] mod = FreeCAD.getImportType(ext) if len(mod) == 0: print("Cannot load file {}".format(input_file)) return # use the first listed module module = importlib.import_module(mod[0]) module.open(input_file) doc = FreeCAD.ActiveDocument if doc is None: print("No active document") return init_gui() nodes = [FreeCADGui.subgraphFromObject(obj) for obj in doc.Objects] # add light and camera so that the rendered geometry is visible root = coin.SoSeparator() light = coin.SoDirectionalLight() cam = coin.SoOrthographicCamera() root.addChild(cam) root.addChild(light) for node in nodes: root.addChild(node) # do the rendering now axo = coin.SbRotation(-0.353553, -0.146447, -0.353553, -0.853553) width = size height = size viewport = coin.SbViewportRegion(width, height) cam.orientation.setValue(axo) cam.viewAll(root, viewport) off = FreeCADGui.SoQtOffscreenRenderer(width, height) off.setBackgroundColor(1, 1, 1) root.ref() # A QGuiApplication is needed to create an OpenGL context if QtGui.QGuiApplication.instance() is None: app = QtGui.QGuiApplication(sys.argv) off.render(root) off.writeToImage(output_file) root.unref()
def resizeGL(self, width, height): vp = coin.SbViewportRegion(width, height) self.sorendermanager.setViewportRegion(vp) self.soeventmanager.setViewportRegion(vp)
base.rgb.setValue(0.6, 0.7, 1.0) data.insertChild(base, 0) print('2') # add light and camera so that the rendered geometry is visible root = coin.SoSeparator() light = coin.SoDirectionalLight() cam = coin.SoOrthographicCamera() root.addChild(cam) root.addChild(light) root.addChild(data) print('3') # do the rendering now axo = coin.SbRotation(-0.353553, -0.146447, -0.353553, -0.853553) viewport = coin.SbViewportRegion(600, 600) cam.orientation.setValue(axo) cam.viewAll(root, viewport) off = coin.SoOffscreenRenderer(viewport) root.ref() off.render(root) root.unref() print('4') # export the image, PS is always available off.writeToPostScript("crystal.ps") print('5') print(dir(off)) # Other formats are only available if simage package is installed