def convertImageToTexture(image): size = coin.SbVec2s(image.width(), image.height()) buffersize = image.byteCount() soImage = coin.SoSFImage() width = size[0] height = size[1] imageBytes = b'' for y in range(height - 1, -1, -1): for x in range(width): rgb = image.pixel(x, y) color = qtutils.QColor() color.setRgba(rgb) alpha = color.alpha() value = 0 if alpha < 255: value = 254 - alpha else: value = color.lightness() if IS_PY_3: imageBytes = imageBytes + chr(value).encode('latin-1') else: imageBytes = imageBytes + chr(value) soImage.setValue(size, 1, imageBytes) return soImage
def coinSetUp(self): #print "coinSetUp" self.TexW = 10 self.TexH = 100 self.sg = FreeCADGui.ActiveDocument.ActiveView.getSceneGraph() #print str( FreeCADGui.ActiveDocument.Document.Label ) #print str( self.sg ) self.stripes = coin.SoTexture2() self.sg.insertChild(self.stripes, 0) self.stripes.filename = "" self.string = '\xff' * 50 + '\x00' * self.StripeWidth self.chars = self.string * self.TexW * self.TexH self.img = coin.SoSFImage() self.img.setValue( coin.SbVec2s(len(self.string) * self.TexW, self.TexH), 1, self.chars) self.stripes.image = self.img # **** here we can transform the texture self.transTexture = coin.SoTexture2Transform() self.sg.insertChild(self.transTexture, 1) #transTexture.translation.setValue(1, 1) self.transTexture.scaleFactor.setValue(self.Scale, self.Scale) self.transTexture.rotation.setValue(1. * self.Rotation / 100) #transTexture.center.setValue(0, .5) self.tc = coin.SoTextureCoordinateEnvironment() self.sg.insertChild(self.tc, 2)
def _reinitTexture(self, obj): if _pixelContainer.get(obj.Name): del _pixelContainer[obj.Name] _pixelContainer[obj.Name] = FPPixelContainer.PixelContainer( obj.ResolutionX, obj.ResolutionY) _pixelContainer[obj.Name].clear(Proto.Color(r=0, g=0, b=0, a=255)) pixelStr = _pixelContainer[obj.Name].toString() resolution = coin.SbVec2s(obj.ResolutionX, obj.ResolutionY) for child in obj.Group: rootNode = child.ViewObject.RootNode # find texture node tex = _findNodeIn(coin.SoTexture2.getClassTypeId(), rootNode) if not tex: #FreeCAD.Console.PrintMessage("inserting new texture\n") tex = coin.SoTexture2() rootNode.insertChild(tex, 1) tex.model = coin.SoTexture2.REPLACE # create the image for the texture image = coin.SoSFImage() #FreeCAD.Console.PrintMessage("Initial Texture begin:\n" + self._getTextureString(obj) + "\nTexture End") image.setValue( resolution, FPPixelContainer.PixelContainer.NUM_COLOR_COMPONENTS, pixelStr) tex.image = image # find complexity node complexity = _findNodeIn(coin.SoComplexity.getClassTypeId(), rootNode) if not complexity: #FreeCAD.Console.PrintMessage("inserting new complexity\n") complexity = coin.SoComplexity() rootNode.insertChild(complexity, 1) complexity.textureQuality = 0.00001
def load_texture(filename, size=None, gui=App.GuiUp): """Return a Coin.SoSFImage to use as a texture for a 2D plane. This function only works if the graphical interface is available as the visual properties that can be applied to a shape are attributes of the view provider (`obj.ViewObject`). Parameters ---------- filename: str A path to a pixel image file (PNG) that can be used as a texture on the face of an object. size: tuple of two int, or a single int, optional It defaults to `None`. If a tuple is given, the two values define the width and height in pixels to which the loaded image will be scaled. If it is a single value, it is used for both dimensions. If it is `None`, the size will be determined from the `QImage` created from `filename`. CURRENTLY the input `size` parameter IS NOT USED. It always uses the `QImage` to determine this information. gui: bool, optional It defaults to the value of `App.GuiUp`, which is `True` when the interface exists, and `False` otherwise. This value can be set to `False` to simulate when the interface is not available. Returns ------- coin.SoSFImage An image object with the appropriate size, number of components (grayscale, grayscale and transparency, color, color and transparency), and byte data. It returns `None` if the interface is not available, or if there is a problem creating the image. """ if gui: # from pivy import coin # from PySide import QtGui, QtSvg try: p = QtGui.QImage(filename) if p.isNull(): _wrn("load_texture: " + _tr("image is Null")) if not os.path.exists(filename): raise FileNotFoundError(-1, _tr("filename does not exist " "on the system or " "on the resource file"), filename) # This is buggy so it was de-activated. # # TODO: allow SVGs to use resolutions # if size and (".svg" in filename.lower()): # # this is a pattern, not a texture # if isinstance(size, int): # size = (size, size) # svgr = QtSvg.QSvgRenderer(filename) # p = QtGui.QImage(size[0], size[1], # QtGui.QImage.Format_ARGB32) # pa = QtGui.QPainter() # pa.begin(p) # svgr.render(pa) # pa.end() # else: # p = QtGui.QImage(filename) size = coin.SbVec2s(p.width(), p.height()) buffersize = p.byteCount() width = size[0] height = size[1] numcomponents = int(float(buffersize) / (width * height)) img = coin.SoSFImage() byteList = [] # isPy2 = sys.version_info.major < 3 isPy2 = six.PY2 # The SoSFImage needs to be filled with bytes. # The pixel information is converted into a Qt color, gray, # red, green, blue, or transparency (alpha), # depending on the input image. # # If Python 2 is used, the color is turned into a character, # which is of type 'byte', and added to the byte list. # If Python 3 is used, characters are unicode strings, # so they need to be encoded into 'latin-1' # to produce the correct bytes for the list. for y in range(height): # line = width*numcomponents*(height-(y)); for x in range(width): rgb = p.pixel(x, y) if numcomponents == 1 or numcomponents == 2: gray = chr(QtGui.qGray(rgb)) if isPy2: byteList.append(gray) else: byteList.append(gray.encode('latin-1')) if numcomponents == 2: alpha = chr(QtGui.qAlpha(rgb)) if isPy2: byteList.append(alpha) else: byteList.append(alpha.encode('latin-1')) elif numcomponents == 3 or numcomponents == 4: red = chr(QtGui.qRed(rgb)) green = chr(QtGui.qGreen(rgb)) blue = chr(QtGui.qBlue(rgb)) if isPy2: byteList.append(red) byteList.append(green) byteList.append(blue) else: byteList.append(red.encode('latin-1')) byteList.append(green.encode('latin-1')) byteList.append(blue.encode('latin-1')) if numcomponents == 4: alpha = chr(QtGui.qAlpha(rgb)) if isPy2: byteList.append(alpha) else: byteList.append(alpha.encode('latin-1')) # line += numcomponents _bytes = b"".join(byteList) img.setValue(size, numcomponents, _bytes) except FileNotFoundError as exc: _wrn("load_texture: {0}, {1}".format(exc.strerror, exc.filename)) return None except Exception as exc: _wrn(str(exc)) _wrn("load_texture: " + _tr("unable to load texture")) return None else: return img return None