Jump to content

Create a texture resource from image in a folder


Recommended Posts

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

 

Link to comment

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

  • Like 2
Link to comment
  • 1 year later...
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

  • Like 1
Link to comment
  • 1 month later...
  • 7 months later...

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 by DomC
Type Errors
Link to comment

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

Link to comment
  • 1 month later...

The Size of "10" means, that the width line of the texture is set to 10mm.

image.png.b15936aa42a8abf40031fe3973cb4d17.png

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)

 

  • Like 1
Link to comment
  • 2 months later...

 

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. 

  • Like 1
Link to comment
  • 2 weeks later...

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.

  • Like 1
Link to comment
  • 1 year later...

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!

Link to comment
  • 2 months later...

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)

 

Link to comment
  • 5 weeks later...

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

Link to comment

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...