loadPrcFileData - change data on the fly

Could someone please inform me if it is possible to change the Showbase’s model-path on the fly, i.e. when loading .obj files in a loop, each with a different sub directory and if so how?
I can load the actual .obj files in a loop from their specific directories but the loader doesn’t process the .mtl files etc. as it does when they are in the model-path directory.

I loaded the PrcFileData into my script (as per grateful advice) which allows me to open a .obj file and have it read the associated .mtl file and all jpgs, pngs etc…from the designated path
loadPrcFileData(‘’, “model-path $MAIN_DIR/models”)
provided that all the file .mtl etc are in the models sub directory as specified in the loadPrcFileData

However I need to read in (load) multiple .obj files and they reside in different directories due to conflicts with material files (jpgs etc) and the fact that the zip files from the ‘modeling program’ (SweetHome3D) exports the models in a zip file containing ‘sub models’ in different directories’

I have spent a delightful number of hours attempting to get the system to accept the ammended directory

mps = (‘’, “model-path $MAIN_DIR/models”) as original in file to i.e. mps = (‘’, “model-path $MAIN_DIR/models/somesubdir”)
i…e x = “‘’, ‘model-path $MAIN_DIR/models’”
y = ‘/somesubdir’
z = x+y
loadPRCFileData(z)

TypeError: unsupported operand type(s) for +: ‘panda3d.core.ConfigPage’ and ‘str’

loadPrcFileData(mps) → TypeError: a bytes-like object is required, not ‘tuple’

tried this
sd = ‘/subdir’
mps = mps + sd
loadPrcFileData(mps)
i.e.
mps = (“‘’, ‘model-path $MAIN_DIR/models/subdir’”)
mpsb = str.encode(mps)
Print(mpsb) → b"‘’, ‘model-path $MAIN_DIR/models’" (looks ok to me BUT)
loadPrcFileData(mpsb)
→ TypeError: load_prc_file_data() missing required argument ‘data’ (pos 2)
[the comma is there but assume as its part of the single variable …

modelPath =loadPrcFileData(‘’, “model-path $MAIN_DIR/models”)

to modelPath =loadPrcFileData(‘’, “model-path $MAIN_DIR/models/G”)

TypeError: unsupported operand type(s) for +: ‘panda3d.core.ConfigPage’ and ‘str’

next try a = bytes(‘//G’,“UTF-8”)
modelPath =modelPath + a

TypeError: unsupported operand type(s) for +: ‘panda3d.core.ConfigPage’ and ‘bytes’

tried
mpsb = str.encode(mps)
TypeError: load_prc_file_data() missing required argument ‘data’ (pos 2)

I have given up on this (beyond my paygrade) - desperately need help (expertise Please)

there is something in the Panda3D Manual ;
To manipulate this variable procedurally, use code not unlike the following, which creates an object of class ConfigVariableString and then manipulates it using the methods setValue() and getValue().

from panda3d.core import ConfigVariableString

myGameServer = ConfigVariableString(‘my-game-server’, ‘127.0.0.1’)
print('Server specified in config file: ', myGameServer.getValue())

Allow the user to change servers on the command-line.

if (sys.argv[1] == ‘–server’):
myGameServer.setValue(sys.argv[2])
print('Server that we will use: ', myGameServer.getValue())

then it mentions ConfigVariableSearchPath so

        **modelPath = ConfigVariableSearchPath.setValue(mp)**

response:
AttributeError: type object ‘panda3d.core.ConfigVariableSearchPath’ has no attribute ‘setValue’

I have poked around Loader.py thinking I might be able to force it to process the .mtl file et al but again beyond my paygrade(could find no mention of if obj or anything…

Alcoholism, suicide or reverting back to day time TV threatens!

if none of this makes any sense please ask for clarification, will try to clarify if insanity hasn’t overcome me.

thanks in advance … Richard

If you wish to modify the model-path at runtime, you can use:


from panda3d.core import getModelPath

path = getModelPath()
path.appendDirectory(...)

It’s a DSearchPath object, see the API reference for more information about how to manipulate it.

Please be mindful of the sensibilities of others on these boards and don’t make jokes about suicide if you don’t get an answer.

First,
I sincerely apologise for any offence I may have inadvertently caused, no offence was intended.

2nd.
Thanks for the reply - but I can not get it to work…
same error as before - OSError: Could not load model file(s): [‘Shape.obj’]

the directories and file names are correct - see at bottom of this (sorry - very long) reply

script is in directory /zip
models directory /zip/models

after loading path
from panda3d.core import getModelPath

modelPath =loadPrcFileData(‘’, “model-path $MAIN_DIR/models”) // as per orig problem

path = getModelPath()
xname = ‘Shape.obj’ # xname comes from loop finding the obj file’s name after extraction from zip

prcdir = ‘/c/12/’ # dir ditto

print(path)

/c/Users/Richard/Documents/Python/Panda/ZipTest/models
/c/Users/Richard/Documents/Python/Panda/ZipTest
/c/Users/Richard/Documents/Panda3D-1.10.13-x64/etc/…
/c/Users/Richard/Documents/Panda3D-1.10.13-x64/etc/…/models

path.appendDirectory(prcdir)

print(path)
/c/Users/Richard/Documents/Python/Panda/ZipTest/models
/c/Users/Richard/Documents/Python/Panda/ZipTest
/c/Users/Richard/Documents/Panda3D-1.10.13-x64/etc/…
/c/Users/Richard/Documents/Panda3D-1.10.13-x64/etc/…/models/C/12/ <== CORRECT

this last entry is correct for the directory of the .obj file (and it does exist

self.environ = self.loader.loadModel(xname,noCache = True)
OSError: Could not load model file(s): [‘Shape.obj’] <==================

note

I have been able to load the .obj files by stringing the paths together BUT the loader ignores both the .mtl file and the material files.

To progress other things i frigged the loadPrcData as below;

match mdir:
case “C\12”:
loadPrcFileData(‘’, “model-path $MAIN_DIR/models/C/12/”)
case “C\13”:
loadPrcFileData(‘’, “model-path $MAIN_DIR/models/C/13/”)
case “C\15”:
loadPrcFileData(‘’, “model-path $MAIN_DIR/models/C/15/”)
case “C\17”:
loadPrcFileData(‘’, “model-path $MAIN_DIR/models/C/17/”)
case “C\22”:
loadPrcFileData(‘’, “model-path $MAIN_DIR/models/C/22/”)
case “C\5”:
loadPrcFileData(‘’, “model-path $MAIN_DIR/models/C/5/”)
case “G”:
loadPrcFileData(‘’, “model-path $MAIN_DIR/models/G/”)
case other: ‘’’

self.environ = self.loader.loadModel(xname,noCache = True)

works perfectly but this means extracting the directories and file names from the zip files which is not really an end result. It seems that p3d requires the loadPrcFileData or model-path to be aware of the model’s path to process the obj file’s references correctly ? - Only an assumption.
Is there a way to modify the loadPrcFileData’s data programmatically within a loop ?

print of the nodes? after loading

0 render/Shape.obj
1 render/Shape.obj
2 render/ceiling-lamp.obj
3 render/texturableTriangle.obj
4 render/texturableCylinder.obj
5 render/texturableBox.obj
6 render/G.obj
7 render/SUV.obj (interesting this file in same dir as G but loading not requested)!* sorry wrong the SUV file name was extracted by the look up routine - didn’t realise this obj file was zipped with the rest .

Again thanks for the reply, Richard

Please note that it’s case-sensitive. Are there any other errors than “Could not load model file”? This could indicate a number of things, which are probably indicated by previous messages.

Sorry for the delay in responding, her who shall not be named had me on house maintenance duties…
No matter what I tried I could not load the models through this, procedure, however by manipulating the returned path from the zip file routine and appending it to the loadPrcFileData string it now loads the obj file and the mtl file plus - the image texture files as well. So all well and tickety boo on this issue. Many thanks for the time and effort expended on this novice.