jonasfehr Posted June 19, 2020 Share Posted June 19, 2020 Hi, I try now to subdivide my question from my previous post - Looking for script to import images as imageprop. Does anyone have a good approach to create a texture resource from images loaded from a folder. I found the example script to load images as symbols(https://developer.vectorworks.net/index.php/Python_Sample_Import_Images_as_Symbols), but I can't figure out how to bind them to a renderworks texture. Afterwards the texture could be used on an extruded object or with a image prob. Cheers Jonas Quote Link to comment
jonasfehr Posted June 19, 2020 Author Share Posted June 19, 2020 I got so far, to create a texture, and add a shaderrecord set to color / image. But how to add a path to a image? h_text = vs.CreateTexture() h_shaderRecord = vs.CreateShaderRecord(h_text, 1, 41) # color image Quote Link to comment
jonasfehr Posted June 22, 2020 Author Share Posted June 22, 2020 Following forum entry says it's not possible with python can someone verify this? Quote Link to comment
Gelde-Aart Posted June 22, 2020 Share Posted June 22, 2020 Hi Jonas, From Vectorworks 2019 and newer it is possible to create a image based texture by using CreateTextureBitmapD (before you had to use a dummy texture...) #Part 1 - import and convert image hPaint = vs.ImportImageFile(thePath, 0,0) #Needs to be deleted afterwards hImage = vs.CreateImageFromPaint(hPaint, 'Just_a_name') #Part 2 - Create ShaderRecord and convert to TextureBitmap hShaderRec = vs.CreateShaderRecord(hTexture, 1, 41) #1 = Color image hTextureBitMap = vs.CreateTextureBitmapD( hShaderRec) #Part 3 - Connect the image to the TextureBitmap vs.SetObjectVariableHandle(hTextureBitMap, 528, hImage) #Were the magic happens! Hope this helps. 🙂 Gelde-Aart 2 Quote Link to comment
jonasfehr Posted June 22, 2020 Author Share Posted June 22, 2020 I was missing the magic... thanks a lot! @Gelde-Aart you are my hero.... Quote Link to comment
Popular Post jonasfehr Posted June 22, 2020 Author Popular Post Share Posted June 22, 2020 Here my complete script to choose a folder and import the images as rendertexture: import os major, minor, maintenance, platform = vs.GetVersion() isMac = False if platform == 1: isMac = True # define a location to import the images importPt = (0,0) symCreatedCnt = 0 err, dirPath = vs.GetFolder( 'Select a Folder' ) if err == 0: # no-error hsfDirPath = dirPath if isMac: ok, hsfDirPath = vs.ConvertPosix2HSFPath( dirPath ) fileIndex = 1 while True: # loop the files fileName = vs.GetFilesInFolder( hsfDirPath, fileIndex ) fileIndex += 1 if fileName == '': # no more files break name, ext = os.path.splitext( fileName ) if ext.lower() == '.png' or ext.lower() == '.jpg': imagePath = os.path.join( dirPath, fileName ) hPaint = vs.ImportImageFile(imagePath, 0,0) #Needs to be deleted afterwards hImage = vs.CreateImageFromPaint(hPaint, 'Just_a_name') hTexture = vs.CreateTexture() vs.SetName(hTexture, name+"_tex") hShaderRec = vs.CreateShaderRecord(hTexture, 1, 41) #1 = Color image hTextureBitMap = vs.CreateTextureBitmapD( hShaderRec) vs.SetObjectVariableHandle(hTextureBitMap, 528, hImage) #Were the magic happens! vs.DelObject(hPaint) symCreatedCnt += 1 vs.AlrtDialog( 'Done! Imported ', symCreatedCnt , ' images to textures.' ) Hope it is beneficial for other too... 7 1 Quote Link to comment
drelARCH Posted June 22, 2020 Share Posted June 22, 2020 Thanks for sharing this very useful script. Would be possible to modify script to be able to select only one image or selected images instead of whole content of folder? Thanks. Quote Link to comment
jonasfehr Posted June 22, 2020 Author Share Posted June 22, 2020 I don't think so, I can't find any function which returns just some selected files after a folder dialog. But you could add a condition, and just create textures, when the naming fit's some criteria... if "xxx" in name : #create the texture Quote Link to comment
Chris Busch Posted June 29, 2020 Share Posted June 29, 2020 Thank you jonasfehr! Working on an automation project and this is exactly what I was missing! Quote Link to comment
Sasha Posted February 5, 2022 Share Posted February 5, 2022 On 6/22/2020 at 2:20 PM, jonasfehr said: Here my complete script to choose a folder and import the images as rendertexture: import os major, minor, maintenance, platform = vs.GetVersion() isMac = False if platform == 1: isMac = True # define a location to import the images importPt = (0,0) symCreatedCnt = 0 err, dirPath = vs.GetFolder( 'Select a Folder' ) if err == 0: # no-error hsfDirPath = dirPath if isMac: ok, hsfDirPath = vs.ConvertPosix2HSFPath( dirPath ) fileIndex = 1 while True: # loop the files fileName = vs.GetFilesInFolder( hsfDirPath, fileIndex ) fileIndex += 1 if fileName == '': # no more files break name, ext = os.path.splitext( fileName ) if ext.lower() == '.png' or ext.lower() == '.jpg': imagePath = os.path.join( dirPath, fileName ) hPaint = vs.ImportImageFile(imagePath, 0,0) #Needs to be deleted afterwards hImage = vs.CreateImageFromPaint(hPaint, 'Just_a_name') hTexture = vs.CreateTexture() vs.SetName(hTexture, name+"_tex") hShaderRec = vs.CreateShaderRecord(hTexture, 1, 41) #1 = Color image hTextureBitMap = vs.CreateTextureBitmapD( hShaderRec) vs.SetObjectVariableHandle(hTextureBitMap, 528, hImage) #Were the magic happens! vs.DelObject(hPaint) symCreatedCnt += 1 vs.AlrtDialog( 'Done! Imported ', symCreatedCnt , ' images to textures.' ) Hope it is beneficial for other too... Hello. This script has some problems in VW2021. Do you have some updates to code. Problem is when i create file with multiple textures and save to "User Libraries" When apply texture object is black, and texture is missing link with Image file 1 Quote Link to comment
Chris Busch Posted March 10, 2022 Share Posted March 10, 2022 I'm having the same issue as Sasha. When I apply the texture and move the object to a different file, the image is missing from the texture. Does this have something to do with deleting the hPaint object? Thanks! Quote Link to comment
DomC Posted October 17, 2022 Share Posted October 17, 2022 (edited) Hello Try to insert that lines. Looks somehow rude, but it seems to "burn" the image into the texture: Also it fixes the width of the image to (document unit?) 10. vs.SetObjectVariableHandle(hTextureBitMap, 528, hImage) #Were the magic happens! vs.ResetObject(hTexture) vs.SetObjectVariableHandle(hTextureBitMap, 528, hImage) resolutionx = vs.GetObjectVariableLongInt(hPaint,530) resolutiony = vs.GetObjectVariableLongInt(hPaint,531) vs.SetTexBFeatureStart(hTextureBitMap, 0, 0) #pixel start vs.SetTexBFeatureEnd(hTextureBitMap, resolutionx, 0) #pixel End vs.SetTexBitFeatureSize(hTextureBitMap, 10) #size units Edited October 17, 2022 by DomC Type Errors Quote Link to comment
BartHays Posted October 19, 2022 Share Posted October 19, 2022 Hello DomC and all, This is really great. This could solve another problem I have. If I run this script a second time it duplicates the texture with another name ( texture 1, tecture 2, etc.) if it could skip the images with existing texture that would be great! (Even better if it could reload the image file for existing textures and leave all else the same) What do you think? Bart Quote Link to comment
Popular Post DomC Posted October 19, 2022 Popular Post Share Posted October 19, 2022 This one would update or create new textures: import os def put_bitmap_in_texture(hTexture, hPaint, image_size): #hTexture Resource, hPaint hImage = vs.CreateImageFromPaint(hPaint, 'Just_a_name') hShaderRec = vs.CreateShaderRecord(hTexture, 1, 41) #1 = Color image hTextureBitMap = vs.CreateTextureBitmapD( hShaderRec) vs.SetObjectVariableHandle(hTextureBitMap, 528, hImage) #Were the magic happens! vs.ResetObject(hTexture) vs.SetObjectVariableHandle(hTextureBitMap, 528, hImage) resolutionx = vs.GetObjectVariableLongInt(hPaint,530) resolutiony = vs.GetObjectVariableLongInt(hPaint,531) vs.SetTexBFeatureStart(hTextureBitMap, 0, 0) #pixel start vs.SetTexBFeatureEnd(hTextureBitMap, resolutionx, 0) #pixel End vs.SetTexBitFeatureSize(hTextureBitMap, image_size) #size units return hTextureBitMap major, minor, maintenance, platform = vs.GetVersion() isMac = False if platform == 1: isMac = True # define a location to import the images importPt = (0,0) image_size = 10 symCreatedCnt = 0 err, dirPath = vs.GetFolder( 'Select a Folder' ) if err == 0: # no-error hsfDirPath = dirPath if isMac: ok, hsfDirPath = vs.ConvertPosix2HSFPath( dirPath ) name_counter = 1 fileIndex = 1 while True: # loop the files fileName = vs.GetFilesInFolder( hsfDirPath, fileIndex ) fileIndex += 1 if fileName == '': # no more files break name, ext = os.path.splitext( fileName ) if ext.lower() == '.png' or ext.lower() == '.jpg': imagePath = os.path.join( dirPath, fileName ) hPaint = vs.ImportImageFile(imagePath, 0,0) #Needs to be deleted afterwards texture_name = name + "_tex" existing_obj_handle = vs.GetObject(texture_name) update_tex = False if existing_obj_handle != vs.Handle(0): #object already exists obj_type = vs.GetTypeN(existing_obj_handle) if obj_type == 97: #object is already a texture > Update hTexture = existing_obj_handle update_tex = True else: #object exists but is not a texture hTexture = vs.CreateTexture() texture_name = name + str(name_counter) +'_tex' name_counter += 1 hTextureBitMap = put_bitmap_in_texture(hTexture, hPaint, image_size) vs.UpdateThumbnailPreview(hTexture) else: #new texture hTexture = vs.CreateTexture() hTextureBitMap = put_bitmap_in_texture(hTexture, hPaint, image_size) if not update_tex: vs.SetName(hTexture, texture_name) vs.DelObject(hPaint) 5 2 Quote Link to comment
BartHays Posted October 20, 2022 Share Posted October 20, 2022 (edited) Mind Blown, this will save us hours. Many Thanks! Bart Edited October 20, 2022 by BartHays 1 Quote Link to comment
Elite Exhibits Posted December 12, 2022 Share Posted December 12, 2022 DomC Is there a way to charge the size to match known geometry It appears obvious ... change this number - image_size = 10 - except I am unable to change the scrip Suggestions are welcome Peter (¿ Not intended to double post this ?) Quote Link to comment
Dominique Corpataux Posted December 12, 2022 Share Posted December 12, 2022 The Size of "10" means, that the width line of the texture is set to 10mm. If you set your document units to meter as example it will still be 10mm and will show 0.001m. If you want to attach that texture on a 1m x 1m object and it should fit the size you can make the size = 1000 or you can scale the texture mapping by for this object. But this will need another script (Or an enhancement of the import-script) to attach the texture and scale by geometry_size_in_mm divided through 10(or what ever size you imported the texture) 1 Quote Link to comment
Elite Exhibits Posted December 12, 2022 Share Posted December 12, 2022 Much appreciated ... Peter Quote Link to comment
cavan.smith Posted March 3, 2023 Share Posted March 3, 2023 Hi there, Just adding to Doms question, amazing script its saving us so much time, however the image size is too small, we need it to be 1000 instead of 10. Can anyone help with this? when editing the script nothing happens.. Thanks Quote Link to comment
cavan.smith Posted March 4, 2023 Share Posted March 4, 2023 Also is there a way to change from randerworks texture to import as image attribute? Quote Link to comment
DomC Posted March 11, 2023 Share Posted March 11, 2023 On 3/3/2023 at 1:27 AM, cavan.smith said: small, we need it to be 1000 instead of 10. Hi Hm, I was quite sure "SetTexBitFeatureSize" changed once the texture size. However I would confirm, the size is always 10mm, 1cm or 0.01m. So far what seems to change the size (but not as we needed) 1. Changing the Document units to the imperial unit-system inch. Texture size is now 1 inch instead of 10mm but somehow other units do not change the size. 2. If I change the line vs.SetTexBFeatureEnd(hTextureBitMap, int(resolutionx*100), 0) The Size is 100 times bigger but this value is not update till i go into the dialog box of the texture. Also Tried: Layer Scale, Different units, scaling the image, scaling the paint. Reload Document. So it seems, we have not a solution for the default texture size yet. 1 Quote Link to comment
Anthony Esau Posted March 22, 2023 Share Posted March 22, 2023 A bit crude, but you can add the command "vs.EditTexture(hTexture)" to open the texture editor for each modified texture. The user will need to click through all of the boxes that pop up, but it forces a refresh of all the textures with the updated information. In my job, I am constantly importing graphic layouts that were generated in Adobe Illustrator. So the scripts shared in this thread have been incredibly helpful. For my situation, individual sizing of the Renderworks textures can be automated by reading the metadata from the images to calculate what size the images were designed to be. This requires installing the Pillow Python library and adding "from PIL import Image" to the top of the script. Then the following lines are added to the main loop. # Calculate the size (width) of the image with Image.open(imagePath) as pil_image: image_width_px = float(pil_image.size[0]) image_resolution_x = float(pil_image.info["dpi"][0]) image_size = round(image_width_px / image_resolution_x, 3) In my limited testing, Pillow doesn't read the dpi correctly from files created in Photoshop and I haven't tested images generated by other programs. Might need some additional tweaking to work more broadly. For setting the texture size, "vs.SetTextureSize(hTexture, image_size)" has been working well for me. 1 Quote Link to comment
Xinyi.Y Posted May 14 Share Posted May 14 Hi Dom and all, This is a really incredible script and definitely saving a lot of time creating textures in one go, just wondering if there is any way to create the textures while editing the shader Reflectivity - Glow in the script? I can see from the lines that one is enabling to edit the colour shader - image which allows this magic happen, is there anyway we can improve this to edit other effects of the renderworks textures? Thank you in advance! Quote Link to comment
DomC Posted July 29 Share Posted July 29 Small Note to this I needed again the automated creation of textures. So far it seems, that the size of the texture is generally not consistent it the document unit is not in imperial units. Best solution i fount is to #insert at the beginning of the script unit_original_predifined = vs.GetPrefInt(170) vs.SetPrefInt(170, 1) #and reverd back to preview units at the end of the script vs.SetPrefInt(170, unit_original_predifined) Quote Link to comment
DomC Posted August 28 Share Posted August 28 After again i have to use an import for textures. I searched the script reference and found this one: def vs.SetTextureSize(texture, newSize): return None I would say it does exactly what we searched for. size in inch. So if we want the texture should have 1000mm in real world we use newSize = 1000 / 25.4 Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.