Showing preview only (584K chars total). Download the full file or copy to clipboard to get everything.
Repository: carson-katri/dream-textures
Branch: main
Commit: c2622a8a9f1a
Files: 120
Total size: 551.0 KB
Directory structure:
gitextract_7tv49soa/
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.yml
│ │ └── feature_request.md
│ └── workflows/
│ ├── package-release.yml
│ └── stale.yml
├── .gitignore
├── .python_dependencies/
│ └── .gitignore
├── LICENSE
├── README.md
├── __init__.py
├── absolute_path.py
├── api/
│ ├── __init__.py
│ ├── backend/
│ │ ├── __init__.py
│ │ └── backend.py
│ └── models/
│ ├── __init__.py
│ ├── control_net.py
│ ├── fix_it_error.py
│ ├── generation_arguments.py
│ ├── generation_result.py
│ ├── model.py
│ ├── prompt.py
│ ├── seamless_axes.py
│ ├── step_preview_mode.py
│ └── task.py
├── builtin_presets/
│ ├── Debug.py
│ ├── Final.py
│ └── Preview.py
├── classes.py
├── community_backends/
│ └── test.py
├── diffusers_backend.py
├── docs/
│ ├── AI_UPSCALING.md
│ ├── DEVELOPMENT_ENVIRONMENT.md
│ ├── HISTORY.md
│ ├── IMAGE_GENERATION.md
│ ├── INPAINT_OUTPAINT.md
│ ├── RENDER_PASS.md
│ ├── SETUP.md
│ ├── TEXTURE_PROJECTION.md
│ └── assets/
│ └── banner_image_prompt.json
├── engine/
│ ├── __init__.py
│ ├── annotations/
│ │ ├── ade20k.py
│ │ ├── compat.py
│ │ ├── depth.py
│ │ ├── normal.py
│ │ ├── openpose.py
│ │ └── viewport.py
│ ├── engine.py
│ ├── node.py
│ ├── node_executor.py
│ ├── node_tree.py
│ └── nodes/
│ ├── annotation_nodes.py
│ ├── input_nodes.py
│ ├── pipeline_nodes.py
│ └── utility_nodes.py
├── generator_process/
│ ├── __init__.py
│ ├── actions/
│ │ ├── choose_device.py
│ │ ├── control_net.py
│ │ ├── controlnet_aux.py
│ │ ├── convert_original_stable_diffusion_to_diffusers.py
│ │ ├── depth_to_image.py
│ │ ├── detect_seamless/
│ │ │ ├── __init__.py
│ │ │ └── model.npz
│ │ ├── huggingface_hub.py
│ │ ├── image_to_image.py
│ │ ├── inpaint.py
│ │ ├── load_model.py
│ │ ├── outpaint.py
│ │ ├── prompt_to_image.py
│ │ └── upscale.py
│ ├── actor.py
│ ├── block_in_use.py
│ ├── directml_patches.py
│ ├── future.py
│ └── models/
│ ├── __init__.py
│ ├── checkpoint.py
│ ├── image_generation_result.py
│ ├── model_config.py
│ ├── model_type.py
│ ├── optimizations.py
│ ├── scheduler.py
│ └── upscale_tiler.py
├── image_utils.py
├── operators/
│ ├── dream_texture.py
│ ├── inpaint_area_brush.py
│ ├── install_dependencies.py
│ ├── notify_result.py
│ ├── open_latest_version.py
│ ├── project.py
│ ├── upscale.py
│ └── view_history.py
├── preferences.py
├── prompt_engineering.py
├── property_groups/
│ ├── control_net.py
│ ├── dream_prompt.py
│ └── seamless_result.py
├── realtime_viewport.py
├── render_pass.py
├── requirements/
│ ├── linux-rocm.txt
│ ├── mac-mps-cpu.txt
│ ├── win-dml.txt
│ └── win-linux-cuda.txt
├── scripts/
│ ├── train_detect_seamless.py
│ └── zip_dependencies.py
├── sd_configs/
│ ├── cldm_v15.yaml
│ ├── cldm_v21.yaml
│ ├── sd_xl_base.yaml
│ ├── sd_xl_refiner.yaml
│ ├── v1-inference.yaml
│ ├── v2-inference-v.yaml
│ ├── v2-inference.yaml
│ ├── v2-inpainting-inference.yaml
│ └── v2-midas-inference.yaml
├── tools.py
├── ui/
│ ├── panels/
│ │ ├── dream_texture.py
│ │ ├── history.py
│ │ ├── render_properties.py
│ │ └── upscaling.py
│ ├── presets.py
│ └── space_types.py
└── version.py
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms
github: carson-katri # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.yml
================================================
name: Bug Report
description: File a bug report
title: "<title>"
labels: ["bug"]
body:
- type: markdown
attributes:
value: |
Before filing a bug report, [search for an existing issue](https://github.com/carson-katri/dream-textures/issues?q=is%3Aissue).
Also, ensure you are running the [latest version](https://github.com/carson-katri/dream-textures/releases/latest).
- type: textarea
id: description
attributes:
label: Description
description: Provide a clear and concise description of what the bug is.
placeholder: Description
validations:
required: true
- type: textarea
id: steps
attributes:
label: Steps to Reproduce
description: List the steps needed to reproduce the issue.
placeholder: |
1. Go to '...'
2. Click on '...'
validations:
required: true
- type: textarea
id: expected-behavior
attributes:
label: Expected Behavior
description: Describe what you expected to happen.
placeholder: |
The 'action' would do 'some amazing thing'.
validations:
required: true
- type: markdown
attributes:
value: |
Unless you are running on an unsupported platform, ensure you downloaded a [packaged release](https://github.com/carson-katri/dream-textures/releases/latest) and not the source code.
- type: dropdown
id: addon-version
attributes:
label: Addon Version
multiple: false
options:
- Windows (CUDA)
- Windows (DirectML)
- macOS (Apple Silicon)
- Other (Built from source)
validations:
required: true
- type: dropdown
id: blender-version
attributes:
label: Blender Version
multiple: false
options:
- Blender 4.1+
- Blender 3.6 - 4.0
validations:
required: true
- type: dropdown
id: hardware
attributes:
label: GPU
description: NVIDIA 16 series cards are known to have a difficult time running Stable Diffusion. Please see the other issues regarding these cards.
multiple: false
options:
- NVIDIA
- NVIDIA 16 Series
- AMD
- Apple Silicon
- Other
validations:
required: true
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: enhancement
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
================================================
FILE: .github/workflows/package-release.yml
================================================
name: Package Release
on:
push:
branches:
- "releases/**"
workflow_dispatch:
jobs:
package-release:
strategy:
matrix:
platform:
- requirements: win-linux-cuda.txt
os: windows-latest
filename: windows-cuda
- requirements: win-dml.txt
os: windows-latest
filename: windows-directml
- requirements: mac-mps-cpu.txt
os: macos-14
filename: macos-arm
version:
- python: '3.10'
filename_suffix: ''
- python: '3.11'
filename_suffix: '-4-1'
runs-on: ${{ matrix.platform.os }}
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
path: dream_textures
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.version.python }}
cache: 'pip'
cache-dependency-path: '**/${{ matrix.platform.requirements }}'
- name: Install dependencies into target
shell: bash
run: 'python -m pip install -r requirements/${{ matrix.platform.requirements }} --no-cache-dir --target .python_dependencies'
working-directory: dream_textures
- name: Zip dependencies with long paths
shell: bash
run: 'python ./dream_textures/scripts/zip_dependencies.py'
- name: Archive Release
uses: thedoctor0/zip-release@main
with:
type: zip
filename: dream_textures-${{ matrix.platform.filename }}${{ matrix.version.filename_suffix }}.zip
exclusions: '*.git*'
- name: Archive and upload artifact
uses: actions/upload-artifact@v3
with:
name: dream_textures-${{ matrix.platform.filename }}${{ matrix.version.filename_suffix }}
path: dream_textures-${{ matrix.platform.filename }}${{ matrix.version.filename_suffix }}.zip
================================================
FILE: .github/workflows/stale.yml
================================================
name: Close inactive issues
on:
schedule:
- cron: "30 1 * * *"
workflow_dispatch:
jobs:
close-issues:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- uses: actions/stale@v5
with:
days-before-issue-stale: 60
days-before-issue-close: 7
stale-issue-label: "stale"
stale-issue-message: "This issue is stale because it has been open for 60 days with no activity."
close-issue-message: "This issue was closed because it has been inactive for 7 days since being marked as stale."
days-before-pr-stale: -1
days-before-pr-close: -1
repo-token: ${{ secrets.GITHUB_TOKEN }}
only-labels: bug
================================================
FILE: .gitignore
================================================
.DS_Store
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.python_dependencies.zip
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
================================================
FILE: .python_dependencies/.gitignore
================================================
*
!.gitignore
================================================
FILE: LICENSE
================================================
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.
================================================
FILE: README.md
================================================

[](https://github.com/carson-katri/dream-textures/releases/latest)
[](https://discord.gg/EmDJ8CaWZ7)
[](https://github.com/carson-katri/dream-textures/releases/latest)
[](https://www.blendermarket.com/products/dream-textures)
* Create textures, concept art, background assets, and more with a simple text prompt
* Use the 'Seamless' option to create textures that tile perfectly with no visible seam
* Texture entire scenes with 'Project Dream Texture' and depth to image
* Re-style animations with the Cycles render pass
* Run the models on your machine to iterate without slowdowns from a service
# Installation
Download the [latest release](https://github.com/carson-katri/dream-textures/releases/latest) and follow the instructions there to get up and running.
> On macOS, it is possible you will run into a quarantine issue with the dependencies. To work around this, run the following command in the app `Terminal`: `xattr -r -d com.apple.quarantine ~/Library/Application\ Support/Blender/3.3/scripts/addons/dream_textures/.python_dependencies`. This will allow the PyTorch `.dylib`s and `.so`s to load without having to manually allow each one in System Preferences.
If you want a visual guide to installation, see this video tutorial from Ashlee Martino-Tarr: https://youtu.be/kEcr8cNmqZk
> Ensure you always install the [latest version](https://github.com/carson-katri/dream-textures/releases/latest) of the add-on if any guides become out of date.
# Usage
Here's a few quick guides:
## [Setting Up](https://github.com/carson-katri/dream-textures/wiki/Setup)
Setup instructions for various platforms and configurations.
## [Image Generation](https://github.com/carson-katri/dream-textures/wiki/Image-Generation)
Create textures, concept art, and more with text prompts. Learn how to use the various configuration options to get exactly what you're looking for.

## [Texture Projection](https://github.com/carson-katri/dream-textures/wiki/Texture-Projection)
Texture entire models and scenes with depth to image.

## [Inpaint/Outpaint](https://github.com/carson-katri/dream-textures/wiki/Inpaint-and-Outpaint)
Inpaint to fix up images and convert existing textures into seamless ones automatically.
Outpaint to increase the size of an image by extending it in any direction.

## [Render Engine](https://github.com/carson-katri/dream-textures/wiki/Render-Engine)
Use the Dream Textures node system to create complex effects.

## [AI Upscaling](https://github.com/carson-katri/dream-textures/wiki/AI-Upscaling)
Upscale your low-res generations 4x.

## [History](https://github.com/carson-katri/dream-textures/wiki/History)
Recall, export, and import history entries for later use.
# Compatibility
Dream Textures has been tested with CUDA and Apple Silicon GPUs. Over 4GB of VRAM is recommended.
If you have an issue with a supported GPU, please create an issue.
### Cloud Processing
If your hardware is unsupported, you can use DreamStudio to process in the cloud. Follow the instructions in the release notes to setup with DreamStudio.
# Contributing
For detailed instructions on installing from source, see the guide on [setting up a development environment](https://github.com/carson-katri/dream-textures/wiki/Setting-Up-a-Development-Environment).
# Troubleshooting
If you are experiencing trouble getting Dream Textures running, check Blender's system console (in the top left under the "Window" dropdown next to "File" and "Edit") for any error messages. Then [search in the issues list](https://github.com/carson-katri/dream-textures/issues?q=is%3Aissue) with your error message and symptoms.
> **Note** On macOS there is no option to open the system console. Instead, you can get logs by opening the app *Terminal*, entering the command `/Applications/Blender.app/Contents/MacOS/Blender` and pressing the Enter key. This will launch Blender and any error messages will show up in the Terminal app.

Features and feedback are also accepted on the issues page. If you have any issues that aren't listed, feel free to add them there!
The [Dream Textures Discord server](https://discord.gg/EmDJ8CaWZ7) also has a common issues list and strong community of helpful people, so feel free to come by for some help there as well.
================================================
FILE: __init__.py
================================================
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTIBILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
bl_info = {
"name": "Dream Textures",
"author": "Dream Textures contributors",
"description": "Use Stable Diffusion to generate unique textures straight from the shader editor.",
"blender": (3, 1, 0),
"version": (0, 4, 1),
"location": "Image Editor -> Sidebar -> Dream",
"category": "Paint"
}
from multiprocessing import current_process
if current_process().name != "__actor__":
import bpy
from bpy.props import IntProperty, PointerProperty, EnumProperty, BoolProperty, CollectionProperty
import sys
import os
module_name = os.path.basename(os.path.dirname(__file__))
def clear_modules():
for name in list(sys.modules.keys()):
if name.startswith(module_name) and name != module_name:
del sys.modules[name]
clear_modules() # keep before all addon imports
from .render_pass import register_render_pass, unregister_render_pass, pass_inputs
from .prompt_engineering import *
from .operators.open_latest_version import check_for_updates
from .operators.project import framebuffer_arguments
from .classes import CLASSES, PREFERENCE_CLASSES
from .tools import TOOLS
from .operators.dream_texture import DreamTexture, kill_generator
from .property_groups.dream_prompt import DreamPrompt
from .property_groups.seamless_result import SeamlessResult
from .ui.presets import register_default_presets
from . import engine
from .diffusers_backend import DiffusersBackend
requirements_path_items = (
('requirements/win-linux-cuda.txt', 'Linux/Windows (CUDA)', 'Linux or Windows with NVIDIA GPU'),
('requirements/mac-mps-cpu.txt', 'Apple Silicon', 'Apple M1/M2'),
('requirements/linux-rocm.txt', 'Linux (AMD)', 'Linux with AMD GPU'),
('requirements/win-dml.txt', 'Windows (DirectML)', 'Windows with DirectX 12 GPU'),
('requirements/dreamstudio.txt', 'DreamStudio', 'Cloud Compute Service')
)
def register():
dt_op = bpy.ops
for name in DreamTexture.bl_idname.split("."):
dt_op = getattr(dt_op, name)
if hasattr(bpy.types, dt_op.idname()): # objects under bpy.ops are created on the fly, have to check that it actually exists a little differently
raise RuntimeError("Another instance of Dream Textures is already running.")
bpy.types.Scene.dream_textures_requirements_path = EnumProperty(name="Platform", items=requirements_path_items, description="Specifies which set of dependencies to install", default='requirements/mac-mps-cpu.txt' if sys.platform == 'darwin' else 'requirements/win-linux-cuda.txt')
for cls in PREFERENCE_CLASSES:
bpy.utils.register_class(cls)
bpy.types.Scene.dream_textures_history = CollectionProperty(type=DreamPrompt)
check_for_updates()
bpy.types.Scene.dream_textures_prompt = PointerProperty(type=DreamPrompt)
bpy.types.Scene.dream_textures_prompt_file = PointerProperty(type=bpy.types.Text)
bpy.types.Scene.init_img = PointerProperty(name="Init Image", type=bpy.types.Image)
bpy.types.Scene.init_mask = PointerProperty(name="Init Mask", type=bpy.types.Image)
bpy.types.Scene.init_depth = PointerProperty(name="Init Depth", type=bpy.types.Image, description="Use an existing depth map. Leave blank to generate one from the init image")
bpy.types.Scene.seamless_result = PointerProperty(type=SeamlessResult)
def get_selection_preview(self):
history = bpy.context.scene.dream_textures_history
if self.dream_textures_history_selection > 0 and self.dream_textures_history_selection < len(history):
return history[self.dream_textures_history_selection].generate_prompt()
return ""
bpy.types.Scene.dream_textures_history_selection = IntProperty(default=1)
bpy.types.Scene.dream_textures_history_selection_preview = bpy.props.StringProperty(name="", default="", get=get_selection_preview, set=lambda _, __: None)
bpy.types.Scene.dream_textures_progress = bpy.props.IntProperty(name="", default=0, min=0, max=0)
bpy.types.Scene.dream_textures_info = bpy.props.StringProperty(name="Info")
bpy.types.Scene.dream_textures_last_execution_time = bpy.props.StringProperty(name="Last Execution Time", default="")
bpy.types.Scene.dream_textures_viewport_enabled = BoolProperty(name="Viewport Enabled", default=False)
bpy.types.Scene.dream_textures_render_properties_enabled = BoolProperty(default=False)
bpy.types.Scene.dream_textures_render_properties_prompt = PointerProperty(type=DreamPrompt)
bpy.types.Scene.dream_textures_render_properties_pass_inputs = EnumProperty(name="Pass Inputs", items=pass_inputs)
bpy.types.Scene.dream_textures_upscale_prompt = PointerProperty(type=DreamPrompt)
bpy.types.Scene.dream_textures_upscale_tile_size = IntProperty(name="Tile Size", default=128, step=64, min=64, max=512)
bpy.types.Scene.dream_textures_upscale_blend = IntProperty(name="Blend", default=32, step=8, min=0, max=512)
bpy.types.Scene.dream_textures_upscale_seamless_result = PointerProperty(type=SeamlessResult)
bpy.types.Scene.dream_textures_project_prompt = PointerProperty(type=DreamPrompt)
bpy.types.Scene.dream_textures_project_framebuffer_arguments = EnumProperty(name="Inputs", items=framebuffer_arguments)
bpy.types.Scene.dream_textures_project_bake = BoolProperty(name="Bake", default=False, description="Re-maps the generated texture onto the specified UV map")
def project_use_controlnet(self, context):
if self.dream_textures_project_use_control_net:
if len(self.dream_textures_project_prompt.control_nets) < 1:
self.dream_textures_project_prompt.control_nets.add()
else:
self.dream_textures_project_prompt.control_nets.clear()
bpy.types.Scene.dream_textures_project_use_control_net = BoolProperty(name="Use ControlNet", default=False, description="Use a depth ControlNet instead of a depth model", update=project_use_controlnet)
engine.register()
for cls in CLASSES:
bpy.utils.register_class(cls)
for tool in TOOLS:
bpy.utils.register_tool(tool)
bpy.types.Scene.dream_textures_render_engine = PointerProperty(type=engine.DreamTexturesRenderEngineProperties)
bpy.types.RENDER_PT_context.append(engine.draw_device)
# Monkey patch cycles render passes
register_render_pass()
register_default_presets()
# Register the default backend.
bpy.utils.register_class(DiffusersBackend)
def unregister():
for cls in PREFERENCE_CLASSES:
bpy.utils.unregister_class(cls)
for cls in CLASSES:
bpy.utils.unregister_class(cls)
for tool in TOOLS:
bpy.utils.unregister_tool(tool)
bpy.types.RENDER_PT_context.remove(engine.draw_device)
engine.unregister()
unregister_render_pass()
# Unregister the default backend
bpy.utils.unregister_class(DiffusersBackend)
kill_generator()
================================================
FILE: absolute_path.py
================================================
import os
def absolute_path(component: str):
"""
Returns the absolute path to a file in the addon directory.
Alternative to `os.abspath` that works the same on macOS and Windows.
"""
return os.path.join(os.path.dirname(os.path.realpath(__file__)), component)
REAL_ESRGAN_WEIGHTS_PATH = absolute_path("weights/realesrgan/realesr-general-x4v3.pth")
CLIPSEG_WEIGHTS_PATH = absolute_path("weights/clipseg/rd64-uni.pth")
================================================
FILE: api/__init__.py
================================================
from .models import *
from .backend import *
================================================
FILE: api/backend/__init__.py
================================================
from .backend import *
================================================
FILE: api/backend/backend.py
================================================
try:
import bpy
from typing import Callable, List, Tuple
from ..models.generation_arguments import GenerationArguments
from ..models.generation_result import GenerationResult
from ..models.model import Model
StepCallback = Callable[[List[GenerationResult]], bool]
Callback = Callable[[List[GenerationResult] | Exception], None]
class Backend(bpy.types.PropertyGroup):
"""A backend for Dream Textures.
Provide the following methods to create a valid backend.
```python
def list_models(self) -> List[Model]
def generate(
self,
arguments: GenerationArguments,
step_callback: StepCallback,
callback: Callback
)
```
"""
@classmethod
def register(cls):
from ...property_groups.dream_prompt import DreamPrompt
setattr(DreamPrompt, cls._attribute(), bpy.props.PointerProperty(type=cls))
@classmethod
def unregister(cls):
from ...property_groups.dream_prompt import DreamPrompt
delattr(DreamPrompt, cls._attribute())
@classmethod
def _id(cls) -> str:
return f"{cls.__module__}.{cls.__name__}"
@classmethod
def _attribute(cls) -> str:
return cls._id().replace('.', '_')
@classmethod
def _lookup(cls, id):
return next(
(backend for backend in cls._list_backends() if backend._id() == id),
next(iter(cls._list_backends()), None)
)
@classmethod
def _list_backends(cls):
return cls.__subclasses__()
def list_models(self, context) -> List[Model]:
"""Provide a list of available models.
The `id` of the model will be provided.
"""
...
def list_controlnet_models(self, context) -> List[Model]:
"""Provide a list of available ControlNet models.
The `id` of the model will be provided.
"""
return []
def list_schedulers(self, context) -> List[str]:
"""Provide a list of available schedulers."""
...
def draw_prompt(self, layout, context):
"""Draw additional UI in the 'Prompt' panel"""
...
def draw_advanced(self, layout, context):
"""Draw additional UI in the 'Advanced' panel"""
...
def draw_speed_optimizations(self, layout, context):
"""Draw additional UI in the 'Speed Optimizations' panel"""
...
def draw_memory_optimizations(self, layout, context):
"""Draw additional UI in the 'Memory Optimizations' panel"""
...
def draw_extra(self, layout, context):
"""Draw additional UI in the panel"""
...
def get_batch_size(self, context) -> int:
"""Return the selected batch size for the backend (if applicable).
A default implementation is provided that returns `1`.
"""
return 1
def generate(
self,
arguments: GenerationArguments,
step_callback: StepCallback,
callback: Callback
):
"""
A request to generate an image.
If the `step_callback` returns `False`, the generation should be cancelled.
After cancelling, `callback` should be called with an `InterruptedError`.
"""
...
def validate(
self,
arguments: GenerationArguments
):
"""Validates the given arguments in the UI without generating.
This validation should occur as quickly as possible.
To report problems with the inputs, raise a `ValueError`.
Use the `FixItError` to provide a solution to the problem as well.
```python
if arguments.steps % 2 == 0:
throw FixItError(
"The number of steps is even",
solution=FixItError.UpdateGenerationArgumentsSolution(
title="Add 1 more step",
arguments=dataclasses.replace(
arguments,
steps=arguments.steps + 1
)
)
)
```
"""
...
except:
pass
================================================
FILE: api/models/__init__.py
================================================
from .generation_result import *
from .model import *
from .prompt import *
from .seamless_axes import *
from .step_preview_mode import *
from .task import *
from .fix_it_error import *
================================================
FILE: api/models/control_net.py
================================================
from dataclasses import dataclass
from typing import Tuple, List
from numpy.typing import NDArray
@dataclass
class ControlNet:
model: str
"""The selected ControlNet model used for generation"""
image: NDArray
"""The control image"""
strength: float
"""The strength of the ControlNet's influence"""
================================================
FILE: api/models/fix_it_error.py
================================================
from typing import Callable, Any
from .generation_arguments import GenerationArguments
from dataclasses import dataclass
class FixItError(Exception):
"""An exception with a solution.
Call the `draw` method to render the UI elements responsible for resolving this error.
"""
def __init__(self, message, solution: 'Solution'):
super().__init__(message)
self._solution = solution
def _draw(self, dream_prompt, context, layout):
self._solution._draw(dream_prompt, context, layout)
@dataclass
class Solution:
def _draw(self, dream_prompt, context, layout):
...
@dataclass
class ChangeProperty(Solution):
"""Prompts the user to change the given `property` of the `GenerationArguments`."""
property: str
def _draw(self, dream_prompt, context, layout):
layout.prop(dream_prompt, self.property)
@dataclass
class RunOperator(Solution):
"""Runs the given operator"""
title: str
operator: str
modify_operator: Callable[[Any], None]
def _draw(self, dream_prompt, context, layout):
self.modify_operator(
layout.operator(self.operator, text=self.title)
)
================================================
FILE: api/models/generation_arguments.py
================================================
from dataclasses import dataclass
from typing import Tuple, List
from ..models.task import Task
from ..models.model import Model
from ..models.prompt import Prompt
from ..models.seamless_axes import SeamlessAxes
from ..models.step_preview_mode import StepPreviewMode
from ..models.control_net import ControlNet
@dataclass
class GenerationArguments:
task: Task
"""The type of generation to perform.
Use a match statement to perform different actions based on the selected task.
```python
match task:
case PromptToImage():
...
case ImageToImage(image=image, strength=strength, fit=fit):
...
case Inpaint(image=image, fit=fit, strength=strength, mask_source=mask_source, mask_prompt=mask_prompt, confidence=confidence):
...
case DepthToImage(depth=depth, image=image, strength=strength):
...
case Outpaint(image=image, origin=origin):
...
case _:
raise NotImplementedError()
```
"""
model: Model
"""The selected model.
This is one of the options provided by `Backend.list_models`.
"""
prompt: Prompt
"""The positive and (optionally) negative prompt.
If `prompt.negative` is `None`, then the 'Negative Prompt' panel was disabled by the user.
"""
size: Tuple[int, int] | None
"""The target size of the image, or `None` to use the native size of the model."""
seed: int
"""The random or user-provided seed to use."""
steps: int
"""The number of inference steps to perform."""
guidance_scale: float
"""The selected classifier-free guidance scale."""
scheduler: str
"""The selected scheduler.
This is one of the options provided by `Backend.list_schedulers`.
"""
seamless_axes: SeamlessAxes
"""Which axes to tile seamlessly."""
step_preview_mode: StepPreviewMode
"""The style of preview to display at each step."""
iterations: int
"""The number of images to generate.
The value sent to `callback` should contain the same number of `GenerationResult` instances in a list.
"""
control_nets: List[ControlNet]
@staticmethod
def _map_property_name(name: str) -> str | List[str] | None:
"""Converts a property name from `GenerationArguments` to the corresponding property of a `DreamPrompt`."""
match name:
case "model":
return "model"
case "prompt":
return ["prompt", "use_negative_prompt", "negative_prompt"]
case "prompt.positive":
return "prompt"
case "prompt.negative":
return ["use_negative_prompt", "negative_prompt"]
case "size":
return ["use_size", "width", "height"]
case "seed":
return "seed"
case "steps":
return "steps"
case "guidance_scale":
return "cfg_scale"
case "scheduler":
return "scheduler"
case "seamless_axes":
return "seamless_axes"
case "step_preview_mode":
return "step_preview_mode"
case "iterations":
return "iterations"
case _:
return None
================================================
FILE: api/models/generation_result.py
================================================
from dataclasses import dataclass
from numpy.typing import NDArray
import numpy as np
import math
@dataclass
class GenerationResult:
"""The output of a `Backend`.
Create a result with an `image` and a `seed`.
```python
result = GenerationResult(
progress=3,
total=5,
image=np.zeros((512, 512, 3)),
seed=42
)
```
Alternatively, create a result with just a `title` and progress values.
```python
result = GenerationResult(
progress=3,
total=5,
title="Loading model"
)
```
"""
progress: int
"""The amount out of `total` that has been completed"""
total: int
"""The number of steps to complete"""
seed: int
"""The seed used to generate the image."""
title: str | None = None
"""The name of the currently executing task"""
image: NDArray | None = None
"""The generated image as a Numpy array.
The shape should be `(height, width, channels)`, where `channels` is 3 or 4.
"""
@staticmethod
def tile_images(results: list['GenerationResult']) -> NDArray:
images = [result.image for result in results]
if len(images) == 0:
return None
elif len(images) == 1:
return images[0]
width = images[0].shape[1]
height = images[0].shape[0]
tiles_x = math.ceil(math.sqrt(len(images)))
tiles_y = math.ceil(len(images) / tiles_x)
tiles = np.zeros((height * tiles_y, width * tiles_x, images[0].shape[2]), dtype=images[0].dtype)
bottom_offset = (tiles_x*tiles_y-len(images)) * width // 2
bottom = (tiles_y - 1) * height
for i, image in enumerate(images):
x = i % tiles_x
y = int((i - x) / tiles_x)
x *= width
y *= height
if y == bottom:
x += bottom_offset
tiles[y: y + height, x: x + width] = image
return tiles
================================================
FILE: api/models/model.py
================================================
from dataclasses import dataclass
@dataclass
class Model:
name: str
description: str
id: str
================================================
FILE: api/models/prompt.py
================================================
from dataclasses import dataclass
from typing import List
@dataclass
class Prompt:
positive: str | List[str]
negative: str | List[str] | None
================================================
FILE: api/models/seamless_axes.py
================================================
from enum import Enum
class SeamlessAxes(Enum):
"""Unified handling of seamless axes.
Can be converted from str (id or text) or bool tuple/list (x, y).
Each enum is equal to their respective convertible values.
Special cases:
AUTO: None
OFF: False, empty str
BOTH: True
"""
AUTO = 'auto', 'Auto-detect', None, None
OFF = 'off', 'Off', False, False
HORIZONTAL = 'x', 'X', True, False
VERTICAL = 'y', 'Y', False, True
BOTH = 'xy', 'Both', True, True
def __init__(self, id, text, x, y):
self.id = id
self.text = text
self.x = x
self.y = y
def __eq__(self, other):
if isinstance(other, type(self)):
return self is other
if isinstance(other, str):
return self.id == other or self.text == other or (other == '' and self is self.OFF)
if isinstance(other, (tuple, list)) and len(other) == 2:
return self.x == other[0] and self.y == other[1]
if other is True and self is self.BOTH:
return True
if other is False and self is self.OFF:
return True
if other is None and self is self.AUTO:
return True
return False
def __and__(self, other):
return SeamlessAxes((self.x and other.x, self.y and other.y))
def __or__(self, other):
return SeamlessAxes((self.x or other.x, self.y or other.y))
def __xor__(self, other):
return SeamlessAxes((self.x != other.x, self.y != other.y))
def __invert__(self):
return SeamlessAxes((not self.x, not self.y))
@classmethod
def _missing_(cls, value):
if isinstance(value, str):
if value == '':
return cls.OFF
for e in cls:
if e.id == value or e.text == value:
return e
raise ValueError(f'no {cls.__name__} with id {repr(id)}')
elif isinstance(value, (tuple, list)) and len(value) == 2:
for e in cls:
if e.x == value[0] and e.y == value[1]:
return e
raise ValueError(f'no {cls.__name__} with x {value[0]} and y {value[1]}')
elif value is True:
return cls.BOTH
elif value is False:
return cls.OFF
elif value is None:
return cls.AUTO
raise TypeError(f'expected str, bool, tuple[bool, bool], or None, got {repr(value)}')
def bpy_enum(self, *args):
return self.id, self.text, *args
================================================
FILE: api/models/step_preview_mode.py
================================================
import enum
class StepPreviewMode(enum.Enum):
NONE = "None"
FAST = "Fast"
FAST_BATCH = "Fast (Batch Tiled)"
ACCURATE = "Accurate"
ACCURATE_BATCH = "Accurate (Batch Tiled)"
================================================
FILE: api/models/task.py
================================================
from dataclasses import dataclass
from typing import Tuple
from numpy.typing import NDArray
from enum import IntEnum
class Task:
"""A specific task type.
Access the properties of the task using dot notation.
```python
# Task.ImageToImage
task.image
task.strength
task.fit
```
Switch over the task to perform the correct actions.
```python
match type(task):
case PromptToImage:
...
case ImageToImage:
...
case Inpaint:
...
case DepthToImage:
...
case Outpaint:
...
```
"""
@classmethod
def name(cls) -> str:
"unknown"
"""A human readable name for this task."""
@dataclass
class PromptToImage(Task):
@classmethod
def name(cls):
return "prompt to image"
@dataclass
class ImageToImage(Task):
image: NDArray
strength: float
fit: bool
@classmethod
def name(cls):
return "image to image"
@dataclass
class Inpaint(ImageToImage):
class MaskSource(IntEnum):
ALPHA = 0
PROMPT = 1
mask_source: MaskSource
mask_prompt: str
confidence: float
@classmethod
def name(cls):
return "inpainting"
@dataclass
class DepthToImage(Task):
depth: NDArray | None
image: NDArray | None
strength: float
@classmethod
def name(cls):
return "depth to image"
@dataclass
class Outpaint(Task):
image: NDArray
origin: Tuple[int, int]
@classmethod
def name(cls):
return "outpainting"
@dataclass
class Upscale(Task):
image: NDArray
tile_size: int
blend: int
@classmethod
def name(cls):
return "upscaling"
================================================
FILE: builtin_presets/Debug.py
================================================
import bpy
prompt = bpy.context.scene.dream_textures_prompt
prompt.steps = 20
prompt.cfg_scale = 7.5
prompt.scheduler = 'DPM Solver Multistep'
prompt.step_preview_mode = 'Accurate'
prompt.optimizations_attention_slicing = True
prompt.optimizations_attention_slice_size_src = 'auto'
prompt.optimizations_attention_slice_size = 1
prompt.optimizations_cudnn_benchmark = False
prompt.optimizations_tf32 = False
prompt.optimizations_amp = False
prompt.optimizations_half_precision = True
prompt.optimizations_sequential_cpu_offload = False
prompt.optimizations_channels_last_memory_format = False
prompt.optimizations_batch_size = 1
prompt.optimizations_vae_slicing = True
prompt.optimizations_cpu_only = False
================================================
FILE: builtin_presets/Final.py
================================================
import bpy
prompt = bpy.context.scene.dream_textures_prompt
prompt.steps = 50
prompt.cfg_scale = 7.5
prompt.scheduler = 'DPM Solver Multistep'
prompt.step_preview_mode = 'Fast'
prompt.optimizations_attention_slicing = True
prompt.optimizations_attention_slice_size_src = 'auto'
prompt.optimizations_attention_slice_size = 1
prompt.optimizations_cudnn_benchmark = False
prompt.optimizations_tf32 = False
prompt.optimizations_amp = False
prompt.optimizations_half_precision = True
prompt.optimizations_sequential_cpu_offload = False
prompt.optimizations_channels_last_memory_format = False
prompt.optimizations_batch_size = 1
prompt.optimizations_vae_slicing = True
prompt.optimizations_cpu_only = False
================================================
FILE: builtin_presets/Preview.py
================================================
import bpy
prompt = bpy.context.scene.dream_textures_prompt
prompt.steps = 20
prompt.cfg_scale = 7.5
prompt.scheduler = 'DPM Solver Multistep'
prompt.step_preview_mode = 'Fast'
prompt.optimizations_attention_slicing = True
prompt.optimizations_attention_slice_size_src = 'auto'
prompt.optimizations_attention_slice_size = 1
prompt.optimizations_cudnn_benchmark = False
prompt.optimizations_tf32 = False
prompt.optimizations_amp = False
prompt.optimizations_half_precision = True
prompt.optimizations_sequential_cpu_offload = False
prompt.optimizations_channels_last_memory_format = False
prompt.optimizations_batch_size = 1
prompt.optimizations_vae_slicing = True
prompt.optimizations_cpu_only = False
================================================
FILE: classes.py
================================================
from .operators.install_dependencies import InstallDependencies, UninstallDependencies
from .operators.open_latest_version import OpenLatestVersion
from .operators.dream_texture import DreamTexture, ReleaseGenerator, CancelGenerator
from .operators.view_history import SCENE_UL_HistoryList, RecallHistoryEntry, ClearHistory, RemoveHistorySelection, ExportHistorySelection, ImportPromptFile
from .operators.inpaint_area_brush import InpaintAreaBrushActivated
from .operators.upscale import Upscale
from .operators.project import ProjectDreamTexture, dream_texture_projection_panels
from .operators.notify_result import NotifyResult
from .property_groups.control_net import ControlNet, ControlNetsAdd, ControlNetsRemove, ControlNetsAddMenu, BakeControlNetImage
from .property_groups.dream_prompt import DreamPrompt
from .property_groups.seamless_result import SeamlessResult
from .ui.panels import dream_texture, history, upscaling, render_properties
from .preferences import OpenURL, StableDiffusionPreferences,\
ImportWeights, Model, ModelSearch, InstallModel, PREFERENCES_UL_ModelList,\
CheckpointGroup, LinkCheckpoint, UnlinkCheckpoint, PREFERENCES_UL_CheckpointList
from .ui.presets import DREAM_PT_AdvancedPresets, DREAM_MT_AdvancedPresets, AddAdvancedPreset, RestoreDefaultPresets
from . import engine
CLASSES = (
*render_properties.render_properties_panels(),
DreamTexture,
ReleaseGenerator,
CancelGenerator,
OpenLatestVersion,
SCENE_UL_HistoryList,
RecallHistoryEntry,
ClearHistory,
RemoveHistorySelection,
ExportHistorySelection,
ImportPromptFile,
InpaintAreaBrushActivated,
Upscale,
ProjectDreamTexture,
ControlNetsAddMenu,
ControlNetsAdd,
ControlNetsRemove,
BakeControlNetImage,
DREAM_PT_AdvancedPresets,
DREAM_MT_AdvancedPresets,
AddAdvancedPreset,
NotifyResult,
engine.DreamTexturesRenderEngineProperties,
engine.DreamTexturesRenderEngine,
engine.NewEngineNodeTree,
*engine.engine_panels(),
# The order these are registered in matters
*dream_texture.dream_texture_panels(),
*upscaling.upscaling_panels(),
*history.history_panels(),
*dream_texture_projection_panels(),
)
PREFERENCE_CLASSES = (
PREFERENCES_UL_ModelList,
ModelSearch,
InstallModel,
Model,
ControlNet,
DreamPrompt,
SeamlessResult,
UninstallDependencies,
InstallDependencies,
OpenURL,
ImportWeights,
RestoreDefaultPresets,
CheckpointGroup,
LinkCheckpoint,
UnlinkCheckpoint,
PREFERENCES_UL_CheckpointList,
StableDiffusionPreferences,
)
================================================
FILE: community_backends/test.py
================================================
bl_info = {
"name": "Test Backend",
"blender": (3, 1, 0),
"category": "Paint",
}
import bpy
from typing import List, Tuple
from dream_textures.api import *
class TestBackend(Backend):
name = "Test"
description = "A short description of this backend"
custom_optimization: bpy.props.BoolProperty(name="My Custom Optimization")
def list_models(self, context) -> List[Model]:
return []
def list_schedulers(self, context) -> List[str]:
return []
def generate(self, task: Task, model: Model, prompt: Prompt, size: Tuple[int, int] | None, seed: int, steps: int, guidance_scale: float, scheduler: str, seamless_axes: SeamlessAxes, step_preview_mode: StepPreviewMode, iterations: int, step_callback: StepCallback, callback: Callback):
raise NotImplementedError()
def draw_speed_optimizations(self, layout, context):
layout.prop(self, "custom_optimization")
def register():
bpy.utils.register_class(TestBackend)
def unregister():
bpy.utils.unregister_class(TestBackend)
================================================
FILE: diffusers_backend.py
================================================
import bpy
from bpy.props import FloatProperty, IntProperty, EnumProperty, BoolProperty
from typing import List
from .api import Backend, StepCallback, Callback
from .api.models import Model, GenerationArguments, GenerationResult
from .api.models.task import PromptToImage, ImageToImage, Inpaint, DepthToImage, Outpaint, Upscale
from .api.models.fix_it_error import FixItError
from .generator_process import Generator
from .generator_process.future import Future
from .generator_process.models import CPUOffload, ModelType, Optimizations, Scheduler
from .preferences import checkpoint_lookup, StableDiffusionPreferences, _template_model_download_progress, InstallModel, model_lookup
from functools import reduce
def _convert_models(models):
return [
None if model is None else (model.id, model.name, model.description)
for model in models
]
class DiffusersBackend(Backend):
name = "HuggingFace Diffusers"
description = "Local image generation inside of Blender"
attention_slicing: BoolProperty(name="Attention Slicing", default=True, description="Computes attention in several steps. Saves some memory in exchange for a small speed decrease")
attention_slice_size_src: EnumProperty(
name="Attention Slice Size",
items=(
("auto", "Automatic", "Computes attention in two steps", 1),
("manual", "Manual", "Computes attention in `attention_head_dim // size` steps. A smaller `size` saves more memory.\n"
"`attention_head_dim` must be a multiple of `size`, otherwise the image won't generate properly.\n"
"`attention_head_dim` can be found within the model snapshot's unet/config.json file", 2)
),
default=1
)
attention_slice_size: IntProperty(name="Attention Slice Size", default=1, min=1)
cudnn_benchmark: BoolProperty(name="cuDNN Benchmark", description="Allows cuDNN to benchmark multiple convolution algorithms and select the fastest", default=False)
tf32: BoolProperty(name="TF32", description="Utilizes tensor cores on Ampere (RTX 30xx) or newer GPUs for matrix multiplications.\nHas no effect if half precision is enabled", default=False)
half_precision: BoolProperty(name="Half Precision", description="Reduces memory usage and increases speed in exchange for a slight loss in image quality.\nHas no effect if CPU only is enabled or using a GTX 16xx GPU", default=True)
cpu_offload: EnumProperty(
name="CPU Offload",
items=(
("off", "Off", "", 0),
("model", "Model", "Some memory savings with minimal speed penalty", 1),
("submodule", "Submodule", "Better memory savings with large speed penalty", 2)
),
default=0,
description="Dynamically moves models in and out of device memory for reduced memory usage with reduced speed"
)
channels_last_memory_format: BoolProperty(name="Channels Last Memory Format", description="An alternative way of ordering NCHW tensors that may be faster or slower depending on the device", default=False)
sdp_attention: BoolProperty(
name="SDP Attention",
description="Scaled dot product attention requires less memory and often comes with a good speed increase.\n"
"Prompt recall may not produce the exact same image, but usually only minor noise differences.\n"
"Overrides attention slicing",
default=True
)
batch_size: IntProperty(name="Batch Size", default=1, min=1, description="Improves speed when using iterations or upscaling in exchange for higher memory usage.\nHighly recommended to use with VAE slicing enabled")
vae_slicing: BoolProperty(name="VAE Slicing", description="Reduces memory usage of batched VAE decoding. Has no effect if batch size is 1.\nMay have a small performance improvement with large batches", default=True)
vae_tiling: EnumProperty(
name="VAE Tiling",
items=(
("off", "Off", "", 0),
("half", "Half", "Uses tiles of half the selected model's default size. Likely to cause noticeably inaccurate colors", 1),
("full", "Full", "Uses tiles of the selected model's default size, intended for use where image size is manually set higher. May cause slightly inaccurate colors", 2),
("manual", "Manual", "", 3)
),
default=0,
description="Decodes generated images in tiled regions to reduce memory usage in exchange for longer decode time and less accurate colors.\nCan allow for generating larger images that would otherwise run out of memory on the final step"
)
vae_tile_size: IntProperty(name="VAE Tile Size", min=1, default=512, description="Width and height measurement of tiles. Smaller sizes are more likely to cause inaccurate colors and other undesired artifacts")
vae_tile_blend: IntProperty(name="VAE Tile Blend", min=0, default=64, description="Minimum amount of how much each edge of a tile will intersect its adjacent tile")
cfg_end: FloatProperty(name="CFG End", min=0, max=1, default=1, description="The percentage of steps to complete before disabling classifier-free guidance")
cpu_only: BoolProperty(name="CPU Only", default=False, description="Disables GPU acceleration and is extremely slow")
use_sdxl_refiner: BoolProperty(name="Use SDXL Refiner", default=False, description="Provide a refiner model to run automatically after the initial generation")
sdxl_refiner_model: EnumProperty(name="SDXL Refiner Model", items=lambda self, context: _convert_models(self.list_models(context)), description="Specify which model to use as a refiner")
def list_models(self, context):
def model_case(model, i):
return Model(
name=model.model_base.replace('models--', '').replace('--', '/'),
description=ModelType[model.model_type].name,
id=model.model_base.replace('models--', '').replace('--', '/')
)
models = {}
for i, model in enumerate(context.preferences.addons[StableDiffusionPreferences.bl_idname].preferences.installed_models):
if model.model_type in {ModelType.CONTROL_NET.name, ModelType.UNKNOWN.name}:
continue
if model.model_type not in models:
models[model.model_type] = [model_case(model, i)]
else:
models[model.model_type].append(model_case(model, i))
return reduce(
lambda a, b: a + [None] + sorted(b, key=lambda m: m.id),
[
models[group]
for group in sorted(models.keys())
],
[]
)
def list_controlnet_models(self, context):
return [
Model(
name=model.model_base.replace('models--', '').replace('--', '/'),
description="ControlNet",
id=model.model_base.replace('models--', '').replace('--', '/')
)
for model in context.preferences.addons[StableDiffusionPreferences.bl_idname].preferences.installed_models
if model.model_type == ModelType.CONTROL_NET.name
]
def list_schedulers(self, context) -> List[str]:
return [scheduler.value for scheduler in Scheduler]
def get_batch_size(self, context) -> int:
return self.batch_size
def optimizations(self) -> Optimizations:
optimizations = Optimizations()
for prop in dir(self):
if hasattr(optimizations, prop) and not prop.startswith('__'):
setattr(optimizations, prop, getattr(self, prop))
if self.attention_slice_size_src == 'auto':
optimizations.attention_slice_size = 'auto'
optimizations.cpu_offload = CPUOffload(optimizations.cpu_offload)
return optimizations
def generate(self, arguments: GenerationArguments, step_callback: StepCallback, callback: Callback):
gen = Generator.shared()
common_kwargs = {
'model': checkpoint_lookup.get(arguments.model.id),
'scheduler': Scheduler(arguments.scheduler),
'optimizations': self.optimizations(),
'prompt': arguments.prompt.positive,
'steps': arguments.steps,
'width': arguments.size[0] if arguments.size is not None else None,
'height': arguments.size[1] if arguments.size is not None else None,
'seed': arguments.seed,
'cfg_scale': arguments.guidance_scale,
'use_negative_prompt': arguments.prompt.negative is not None,
'negative_prompt': arguments.prompt.negative or "",
'seamless_axes': arguments.seamless_axes,
'iterations': arguments.iterations,
'step_preview_mode': arguments.step_preview_mode,
'sdxl_refiner_model': (checkpoint_lookup.get(self.sdxl_refiner_model) if self.use_sdxl_refiner else None),
}
future: Future
match arguments.task:
case PromptToImage():
if len(arguments.control_nets) > 0:
future = gen.control_net(
**common_kwargs,
control_net=[checkpoint_lookup.get(c.model) for c in arguments.control_nets],
control=[c.image for c in arguments.control_nets],
controlnet_conditioning_scale=[c.strength for c in arguments.control_nets],
image=None,
inpaint=False,
inpaint_mask_src='alpha',
text_mask='',
text_mask_confidence=1,
strength=1
)
else:
future = gen.prompt_to_image(**common_kwargs)
case Inpaint(image=image, fit=fit, strength=strength, mask_source=mask_source, mask_prompt=mask_prompt, confidence=confidence):
if len(arguments.control_nets) > 0:
future = gen.control_net(
**common_kwargs,
control_net=[c.model for c in arguments.control_nets],
control=[c.image for c in arguments.control_nets],
controlnet_conditioning_scale=[c.strength for c in arguments.control_nets],
image=image,
inpaint=True,
inpaint_mask_src='alpha' if mask_source == Inpaint.MaskSource.ALPHA else 'prompt',
text_mask=mask_prompt,
text_mask_confidence=confidence,
strength=strength
)
else:
future = gen.inpaint(
image=image,
fit=fit,
strength=strength,
inpaint_mask_src='alpha' if mask_source == Inpaint.MaskSource.ALPHA else 'prompt',
text_mask=mask_prompt,
text_mask_confidence=confidence,
**common_kwargs
)
case ImageToImage(image=image, strength=strength, fit=fit):
if len(arguments.control_nets) > 0:
future = gen.control_net(
**common_kwargs,
control_net=[c.model for c in arguments.control_nets],
control=[c.image for c in arguments.control_nets],
controlnet_conditioning_scale=[c.strength for c in arguments.control_nets],
image=image,
inpaint=False,
inpaint_mask_src='alpha',
text_mask='',
text_mask_confidence=1,
strength=strength
)
else:
future = gen.image_to_image(image=image, fit=fit, strength=strength, **common_kwargs)
case DepthToImage(depth=depth, image=image, strength=strength):
future = gen.depth_to_image(
depth=depth,
image=image,
strength=strength,
**common_kwargs
)
case Outpaint(image=image, origin=origin):
future = gen.outpaint(
image=image,
outpaint_origin=origin,
fit=False,
strength=1,
inpaint_mask_src='alpha',
text_mask='',
text_mask_confidence=1,
**common_kwargs
)
case Upscale(image=image, tile_size=tile_size, blend=blend):
future = gen.upscale(
image=image,
tile_size=tile_size,
blend=blend,
**common_kwargs
)
case _:
raise NotImplementedError()
def on_step(future: Future, step_image: [GenerationResult]):
should_continue = step_callback(step_image)
if not should_continue:
future.cancel()
callback(InterruptedError())
def on_done(future: Future):
callback(future.result(last_only=True))
def on_exception(_, exception):
callback(exception)
future.add_response_callback(on_step)
future.add_exception_callback(on_exception)
future.add_done_callback(on_done)
def validate(self, arguments: GenerationArguments):
model = None if arguments.model is None else model_lookup.get(arguments.model.id)
if model is None:
raise FixItError("No model selected.", FixItError.ChangeProperty("model"))
else:
if not model.model_type.matches_task(arguments.task):
class DownloadModel(FixItError.Solution):
def _draw(self, dream_prompt, context, layout):
if not _template_model_download_progress(context, layout):
target_model_type = ModelType.from_task(arguments.task)
if target_model_type is not None:
install_model = layout.operator(InstallModel.bl_idname, text=f"Download {target_model_type.recommended_model()} (Recommended)", icon="IMPORT")
install_model.model = target_model_type.recommended_model()
install_model.prefer_fp16_revision = context.preferences.addons[StableDiffusionPreferences.bl_idname].preferences.prefer_fp16_revision
model_task_description = f"""Incorrect model type selected for {type(arguments.task).name().replace('_', ' ').lower()} tasks.
The selected model is for {model.model_type.name.replace('_', ' ').lower()}."""
if not any(m.model_type.matches_task(arguments.task) for m in model_lookup._models.values()):
raise FixItError(
message=model_task_description + "\nYou do not have any compatible models downloaded:",
solution=DownloadModel()
)
else:
raise FixItError(
message=model_task_description + "\nSelect a different model below.",
solution=FixItError.ChangeProperty("model")
)
def draw_advanced(self, layout, context):
layout.prop(self, "use_sdxl_refiner")
col = layout.column()
col.enabled = self.use_sdxl_refiner
col.prop(self, "sdxl_refiner_model")
def draw_speed_optimizations(self, layout, context):
inferred_device = Optimizations.infer_device()
if self.cpu_only:
inferred_device = "cpu"
def optimization(prop):
if Optimizations.device_supports(prop, inferred_device):
layout.prop(self, prop)
optimization("cudnn_benchmark")
optimization("tf32")
optimization("half_precision")
optimization("channels_last_memory_format")
optimization("batch_size")
def draw_memory_optimizations(self, layout, context):
inferred_device = Optimizations.infer_device()
if self.cpu_only:
inferred_device = "cpu"
def optimization(prop):
if Optimizations.device_supports(prop, inferred_device):
layout.prop(self, prop)
optimization("sdp_attention")
optimization("attention_slicing")
slice_size_row = layout.row()
slice_size_row.prop(self, "attention_slice_size_src")
if self.attention_slice_size_src == 'manual':
slice_size_row.prop(self, "attention_slice_size", text="Size")
optimization("cpu_offload")
optimization("cpu_only")
optimization("vae_slicing")
optimization("vae_tiling")
if self.vae_tiling == "manual":
optimization("vae_tile_size")
optimization("vae_tile_blend")
================================================
FILE: docs/AI_UPSCALING.md
================================================
# AI Upscaling
Use the Stable Diffusion upscaler to increase images 4x in size while retaining detail. You can guide the upscaler with a text prompt.
> Upscaling uses the model `stabilityai/stable-diffusion-4x-upscaler`. This model will automatically be downloaded when the operator is first run.
Use the AI Upscaling panel to access this tool.
1. Open the image to upscale in an *Image Editor* space
2. Expand the *AI Upscaling* panel, located in the *Dream* sidebar tab
3. Type a prompt to subtly influence the generation.
4. Optionally configure the tile size, blend, and other advanced options.

The upscaled image will be opened in the *Image Editor*. The image will be named `Source Image Name (Upscaled)`.
## Tile Size
Due to the large VRAM consumption of the `stabilityai/stable-diffusion-4x-upscaler` model, the input image is split into tiles with each tile being upscaled independently, then stitched back together.
The default tile size is 128x128, which will result in an image of size 512x512. These 512x512 images are stitched back together to form the final image.
You can increase or decrease the tile size depending on your GPU's capabilities.
The *Blend* parameter controls how much overlap is included in the tiles to help reduce visible seams.
================================================
FILE: docs/DEVELOPMENT_ENVIRONMENT.md
================================================
# Setting Up a Development Environment
With the following steps, you can start contributing to Dream Textures.
These steps can also be used to setup the add-on on Linux.
## Cloning
A basic knowledge of Git will be necessary to contribute. To start, clone the repository:
```sh
git clone https://github.com/carson-katri/dream-textures.git dream_textures
```
> If you use SSH, clone with `git clone git@github.com:carson-katri/dream-textures.git dream_textures`
This will clone the repository into the `dream_textures` folder.
## Installing to Blender
You can install the add-on to Blender in multiple ways. The easiest way is to copy the folder into the add-ons directory.
This directory is in different places on different systems.
* Windows
* `%USERPROFILE%\AppData\Roaming\Blender Foundation\Blender\3.4\scripts\addons`
* macOS
* `/Users/$USER/Library/Application Support/Blender/3.4/scripts/addons`
* Linux
* `$HOME/.config/blender/3.4/scripts/addons`
> This path may be different depending on how you installed Blender. See [Blender's documentation](https://docs.blender.org/manual/en/latest/advanced/blender_directory_layout.html) for more information on the directory layout.
If you can't find the add-on folder, you can look at another third-party add-on you already have in Blender preferences and see where it is located.

### Using Visual Studio Code
> This is not necessary if you won't be making any changes to Dream Textures or prefer a different IDE.
You can also install and debug the add-on with the [Blender Development]() extension for Visual Studio Code.
Open the `dream_textures` folder in VS Code, open the command palette (Windows: <kbd>Shift</kbd> + <kbd>Ctrl</kbd> + <kbd>P</kbd>, macOS: <kbd>Shift</kbd> + <kbd>Command</kbd> + <kbd>P</kbd>), and search for the command `Blender: Start`.

Then choose which Blender installation to use.

Blender will now start up with the add-on installed. You can verify this by going to Blender's preferences and searching for *Dream Textures*.
## Installing Dependencies
When installing from source, the dependencies are not included. You can install them from Blender's preferences.
First, enable *Developer Extras* so Dream Textures' developer tools will be displayed.

Then, use the *Developer Tools* section to install the dependencies.

### Installing Dependencies Manually
In some cases, the *Install Dependencies* tool may not work. In this case, you can install the dependencies from the command line.
The best way to install dependencies is using the Python that ships with Blender. The command will differ depending on your operating system and Blender installation.
On some platforms, Blender does not come with `pip` pre-installed. You can use `ensurepip` to install it if necessary.
```sh
# Windows
"C:\Program Files\Blender Foundation\Blender 3.4\3.4\python\bin\python.exe" -m ensurepip
# macOS
/Applications/Blender.app/Contents/Resources/3.4/python/bin/python3.10 -m ensurepip
# Linux (via snap)
/snap/blender/3132/3.4/python/bin/python3.10 -m ensurepip
```
Once you have `pip`, the dependencies can be installed.
All of the packages *must* be installed to `dream_textures/.python_dependencies`. The following commands assume they are being run from inside the `dream_textures` folder.
```sh
# Windows
"C:\Program Files\Blender Foundation\Blender 3.4\3.4\python\bin\python.exe" -m pip install -r requirements/win-linux-cuda.txt --target .python_dependencies
# macOS
/Applications/Blender.app/Contents/Resources/3.4/python/bin/python3.10 -m pip install -r requirements/mac-mps-cpu.txt --target .python_dependencies
# Linux (via snap)
/snap/blender/3132/3.4/python/bin/python3.10 -m pip install -r requirements/win-linux-cuda.txt --target .python_dependencies
```
## Using the Add-on
Once you have the dependencies installed, the add-on will become fully usable. Continue setting up as described in the [setup guide](./SETUP.md).
## Common Issues
### macOS
1. On Apple Silicon, with the `requirements-dream-studio.txt` you may run into an error with gRPC using an incompatible binary. If so, please use the following command to install the correct gRPC version:
```sh
pip install --no-binary :all: grpcio --ignore-installed --target .python_dependencies --upgrade
```
================================================
FILE: docs/HISTORY.md
================================================
# History
Each time you generate, the full configuration is saved to the *History* panel. You can recall any previous generation to re-run it by clicking *Recall Prompt*.
## Prompt Import/Export
You can also export the selected prompt to JSON for later import. This is a more permanent way to backup prompts, and can be useful for sharing an exact image.
### Export
1. Select a history entry row
2. Click the export icon button
3. Save the JSON file to your computer

### Import
1. Select the import icon button in the header of the *Dream Texture* panel
2. Open a valid prompt JSON file
3. Every configuration option will be loaded in

================================================
FILE: docs/IMAGE_GENERATION.md
================================================
# Image Generation
1. To open Dream Textures, go to an Image Editor or Shader Editor
1. Ensure the sidebar is visible by pressing *N* or checking *View* > *Sidebar*
2. Select the *Dream* panel to open the interface

Enter a prompt then click *Generate*. It can take anywhere from a few seconds to a few minutes to generate, depending on your GPU.
## Options
### Pipeline
Two options are currently available:
* Stable Diffusion - for local generation
* DreamStudio - for cloud processing
Only the options available for the version you installed and the keys provided in the add-on preferences will be available.
### Model
Choose from any installed model. Some options require specific kinds of model.
For example, []
### Prompt
A few presets are available to help you create great prompts. They work by asking you to fill in a few simple fields, then generate a full prompt string that is passed to Stable Diffusion.
The default preset is *Texture*. It asks for a subject, and adds the word `texture` to the end. So if you enter `brick wall`, it will use the prompt `brick wall texture`.
### Seamless
Checking seamless will use a circular convolution to create a perfectly seamless image, which works great for textures.
You can also specify which axes should be seamless.
### Negative
Enabling negative prompts gives you finer control over your image. For example, if you asked for a `cloud city`, but you wanted to remove the buildings it added, you could enter the negative prompt `building`. This would tell Stable Diffusion to avoid drawing buildings. You can add as much content you want to the negative prompt, and it will avoid everything entered.
### Size
The target image dimensions. The width/height should be a multiple of 64, or it will round to the closest one for you.
Most graphics cards with 4+GB of VRAM should be able to generate 512x512 images. However, if you are getting CUDA memory errors, try decreasing the size.
> Stable Diffusion was trained on 512x512 images, so you will get the best results at this size (or at least when leaving one dimensions at 512).
### Source Image
Choose an image from a specific *File* or use the *Open Image*.
Three actions are available that work on a source image.
#### Modify
Mixes the image with the noise with the ratio specified by the *Noise Strength*. This will make Stable Diffusion match the style, composition, etc. from it.
Stength specifies how much latent noise to mix with the image. A higher strength means more latent noise, and more deviation from the init image. If you want it to stick to the image more, decrease the strength.
> Depending on the strength value, some steps will be skipped. For example, if you specified `10` steps and set strength to `0.5`, only `5` steps would be used.
Fit to width/height will ensure the image is contained within the configured size.
The *Image Type* option has a few options:
1. Color - Mixes the image with noise
> The following options require a depth model to be selected, such as `stabilityai/stable-diffusion-2-depth`. Follow the instructions to [download a model](setup.md#download-a-model).
2. Color and Generated Depth - Uses MiDaS to infer the depth of the initial image and includes it in the conditioning. Can give results that more closely match the composition of the source image.
3. Color and Depth Map - Specify a secondary image to use as the depth map, instead of generating one with MiDaS.
4. Depth - Treats the intial image as a depth map, and ignores any color. The generated image will match the composition but not colors of the original.
### Advanced
You can have more control over the generation by trying different values for these parameters:
* Random Seed - When enabled, a seed will be selected for you
* Seed - The value used to seed RNG, if text is input instead of a number its hash will be used
* Steps - Number of sampler steps, higher steps will give the sampler more time to converge and clear up artifacts
* CFG Scale - How strongly the prompt influences the output
* Scheduler - Some schedulers take fewer steps to produce a good result than others. Try each one and see what you prefer.
* Step Preview - Whether to show each step in the image editor. Defaults to 'Fast', which samples the latents without using the VAE. 'Accurrate' will run the latents through the VAE at each step and slow down generation significantly.
* Speed Optimizations - Various optimizations to increase generation speed, some at the cost of VRAM. Recommended default is *Half Precision*.
* Memory Optimizations - Various optimizations to reduce VRAM consumption, some at the cost of speed. Recommended default is *Attention Slicing* with *Automatic* slice size.
### Iterations
How many images to generate. This is only particularly useful when *Random Seed* is enabled.
================================================
FILE: docs/INPAINT_OUTPAINT.md
================================================
# Inpaint/Outpaint
This guide shows how to use both [inpainting](#inpainting) and [outpainting](#outpainting).
> For both inpainting and outpainting you *must* use a model fine-tuned for inpainting, such as `stabilityai/stable-diffusion-2-inpainting`. Follow the instructions to [download a model](setup.md#download-a-model).
# Inpainting
Inpainting refers to filling in or replacing parts of an image. It can also be used to [make existing textures seamless](#making-textures-seamless).
The quickest way to inpaint is with the *Mark Inpaint Area* brush.
1. Use the *Mark Inpaint Area* brush to remove the edges of the image
2. Enter a prompt for what should fill the erased area
3. Enable *Source Image*, select the *Open Image* source and the *Inpaint* action
4. Choose the *Alpha Channel* mask source
5. Click *Generate*

## Making Textures Seamless
Inpainting can also be used to make an existing texture seamless.
1. Use the *Mark Inpaint Area* brush to remove the edges of the image
2. Enter a prompt that describes the texture, and check *Seamless*
3. Enable *Source Image*, select the *Open Image* source and the *Inpaint* action
4. Click *Generate*

# Outpainting
Outpainting refers to extending an image beyond its original size. Use an inpainting model such as `stabilityai/stable-diffusion-2-inpainting` for outpainting as well.
1. Select an image to outpaint and open it in an Image Editor
2. Choose a size, this is how large the outpaint will be
3. Enable *Source Image*, select the *Open Image* source and the *Outpaint* action
4. Set the origin of the outpaint. See [Choosing an Origin](#choosing-an-origin) for more info.
### Choosing an Origin
The top left corner of the image is (0, 0), with the bottom right corner being the (width, height).
You should always include overlap or the outpaint will be completely unrelated to the original. The add-on will warn you if you do not include any.
Take the image below for example. We want to outpaint the bottom right side. Let's figure out the correct origin.
Here's what we know:
1. We know our image is 512x960. You can find this in the sidebar on the *Image* tab.
2. We set the size of the outpaint to 512x512 in the *Dream* tab
With this information we can calculate:
1. The X origin will be the width of the image minus some overlap. The width is 512px, and we want 64px of overlap. So the X origin will be set to `512 - 64` or `448`.
2. The Y origin will be the height of the image minus the height of the outpaint size. The height of the image is 960px, and the height of the outpaint is 512px. So the Y origin will be set to `960 - 512` or `448`.
> Tip: You can enter math expressions into any Blender input field.

After selecting this origin, we can outpaint the bottom right side.

Here are other values we could have used for other parts of the image:
* Bottom Left: `(-512 + 64, 512 - 64)` or `(-448, 448)`
* Top Right: `(512 - 64, 0)` or `(448, 0)`
* Top Left: `(-512 + 64, 0)` or `(-448, 0)`
* Top: `(0, 0)`
* Bottom: `(0, 512 - 64)` or `(0, 448)`
================================================
FILE: docs/RENDER_PASS.md
================================================
# Render Pass
A custom 'Dream Textures' render pass is available for Cycles. This allows you to run Dream Textures on the render result each time the scene is rendered. It works with animations as well, and can be used to perform style transfer on each frame of an animation.
> The render pass and Cycles will both use significant amounts of VRAM depending on the scene. You can use the CPU to render on Cycles to save resources for Dream Textures.
1. In the *Render Properties* panel, switch to the *Cycles* render engine
> In the *Output Properties* panel, ensure the image size is reasonable for your GPU and Stable Diffusion. 512x512 is a good place to start.

2. Enable the *Dream Textures* render pass, and enter a text prompt. You can also specify which pass inputs to use. Using depth information can help the rendered result match the scene geometry.
> When using depth, you *must* select a depth model, such as `stabilityai/stable-diffusion-2-depth`. Follow the instructions to [download a model](setup.md#download-a-model).

3. To use the Dream Textures generated image as the final result, open the *Compositor* space
4. Enable *Use Nodes*
5. Connect the *Dream Textures* socket from the *Render Layers* node to the *Image* socket of the *Composite* node

Now whenever you render your scene, it will automatically run through Stable Diffusion and output the result.
Here's an example using only the *Depth* pass as input.

## Controlling the Output
### Depth
Using a depth model and choosing *Pass Inputs* such as *Depth* or *Color and Depth* can go a long way in making the result closely match the geometry of your scene.
### Noise Strength
The noise strength parameter is very important when using this render pass. It is the same as *Noise Strength* described in [Image Generation](IMAGE_GENERATION.md#modify). If you want your scene composition, colors, etc. to be preserved, use a lower strength value. If you want Stable Diffusion to take more control, use a higher strength value.
This does not apply when using the *Depth* pass input and no color.
### Seed
Enabling *Random Seed* can give you some cool effects, and allow for more experimentation. However, if you are trying to do simple style transfer on an animation, using a consistent seed can help the animation be more coherent.
## Animation
You can animate most of the properties when using the render pass. Simply create keyframes as you typically would in Blender, and the properties will automatically be updated for each frame.
================================================
FILE: docs/SETUP.md
================================================
# Setting Up
Getting up and running is easy. Make sure you have several GBs of storage free, as the model weights and add-on consume a lot of storage space.
In general, all of the instructions you need to setup will be given within Blender. However, if you want to see screenshots and more explanation this can be helpful.
If you have any problems, you can get help in the [Dream Textures Discord server](https://discord.gg/EmDJ8CaWZ7).
## Installation
See the [release notes](https://github.com/carson-katri/dream-textures/releases/latest) for the most recent version of Dream Textures. There you will find a section titled "Choose Your Installation". Use the dropdowns to find the right version for your system.
> The add-on archive for Windows is compressed with 7-Zip to fit within GitHub's file size limits. Follow the instructions on the release notes page to extract the contained `.zip` file.
After you have the add-on installed in Blender, check the box in Blender preferences to enable it. Then follow the steps below to complete setup.
If you downloaded a DreamStudio-only version, you can skip to the [DreamStudio section](#dreamstudio).
> **DO NOT** try to install dependencies. Tools for doing so are intended for development. *Always* [download a prebuilt version](https://github.com/carson-katri/dream-textures/releases/latest).
## Download a Model
There are [hundreds of models](https://huggingface.co/sd-dreambooth-library) to choose from. A good model to start with is `stabilityai/stable-diffusion-2-1-base`. This is the latest 512x512 Stable Diffusion model.
In the add-on preferences, search for this model. Then click the download button on the right.
> Depending on your Internet speeds, it may take a few minutes to download.

### Other Useful Models
There are a few other models you may want to download as well:
* `stabilityai/stable-diffusion-2-inpainting` - Fine-tuned for inpainting, and required to use the [inpaint and outpaint](INPAINT_OUTPAINT.md) features
* `stabilityai/stable-diffusion-2-depth` - Uses depth information to guide generation, required for [texture projection](TEXTURE_PROJECTION.md), the [render pass](RENDER_PASS.md) when using depth pass input, and image to image when using depth
* `stabilityai/stable-diffusion-x4-upscaler` - Upscales the input image 4x, used only for [upscaling](AI_UPSCALING.md)
* `stabilityai/stable-diffusion-2-1` - Fine-tuned for 768x768 images
### Private Models
Some models are gated or private to your account/organization. To download these models, generate a Hugging Face Hub token and paste it in the "Token" field. You can generate a token in your [account settings on Hugging Face](https://huggingface.co/settings/tokens).

### Importing Checkpoints
Dream Textures can also import `.ckpt` files, which you may be familiar with if you've used [AUTOMATIC1111/stable-diffusion-webui](https://github.com/AUTOMATIC1111/stable-diffusion-webui).
Click *Import Checkpoint File* in add-on preferences, then select your checkpoint file. You should also specify what kind of model it is in the sidebar of the file picker.

If you don't see the sidebar, press *N* on your keyboard or click the gear icon in the top right.
Here's what the various *Model Config* options are for:
* `v1` - Weights from the original [CompVis/stable-diffusion](https://github.com/CompVis/stable-diffusion) code, such as `stable-diffusion-v1-x`
* `v2 (512, epsilon)` - Weights from the updated [Stability-AI/stablediffusion](https://github.com/Stability-AI/stablediffusion) code, specifically models with `prediction_type="epsilon"` such as the 512x512 models
* `v2 (768, v_prediction)` - Weights from the updated [Stability-AI/stablediffusion](https://github.com/Stability-AI/stablediffusion) code, specifically models with `prediction_type="v_prediction"` such as the 768x768 models
After choosing the file, the model will be converted to the Diffusers format automatically and be available in your model list.
## DreamStudio
To connect your DreamStudio account, enter your API key in the add-on preferences.

You can find your key in the [account settings page of DreamStudio](https://beta.dreamstudio.ai/membership?tab=apiKeys).

================================================
FILE: docs/TEXTURE_PROJECTION.md
================================================
# Texture Projection
Using depth to image, Dream Textures is able to texture entire scenes automatically with a simple prompt.
It's sort of like [Ian Hubert's method](https://www.youtube.com/watch?v=v_ikG-u_6r0) in reverse. Instead of starting with an image and building geometry around that, we start with the geometry and generate an image that projects perfectly onto it.
> Make sure you download a depth model such as `stabilityai/stable-diffusion-2-depth`. Follow the instructions to [download a model](SETUP.md#download-a-model).
Follow the steps below to project a texture onto your mesh.
## Selecting a Target
In the 3D Viewport, select the objects you want to project onto. Then in edit mode, select all of the faces to target. Only the selected faces will be given the new texture.
Every object in the viewport will be factored into the depth map. To only use the selected objects in the depth map, enter local view by pressing */* or selecting *View* > *Local View* > *Toggle Local View* in the viewport menu bar.
> Tip: Large unbroken faces do not always project well. Try subdividing your mesh if the projection is warping.

## Prompting
In the sidebar, select the "Dream" panel. Choose a depth model from the dropdown, and enter a prompt. All of the options available for image generation are available here as well.
At the bottom you can choose what data to use for the projection. The default is "Depth". You can switch to "Depth and Color" to factor in the current color from the viewport.
> The color data is retrieved from the current viewport. Switch to *Viewport Shading* or *Rendered* view to use the colors specified for EEVEE or Cycles.
You can also adjust the size of the image from the default 512x512. Note that the depth data is in the same aspect ratio as the 3D Viewport window. If you have the Blender window landscape, you may want to adjust the size to be 768x512 or something similar. You could also shrink your window to make it square.
## Project Dream Texture
After configuring everything, click the *Project Dream Texture* button. This will begin the depth to image process.
You are free to move the viewport around as it generates. Switch to *Viewport Shading* mode to see each step as it generates live.
A new material will be added named with the seed of the generated image. The UVs for each selected face are also updated to be projected from the angle the material was generated at.
> Tip: In the sidebar under *View* you can adjust the *Focal Length* of the viewport.

================================================
FILE: docs/assets/banner_image_prompt.json
================================================
{
"prompt_structure": "concept_art",
"use_negative_prompt": true,
"negative_prompt": "person dragon bird ocean buildings woman",
"width": 1024,
"height": 256,
"seamless": false,
"show_advanced": false,
"random_seed": false,
"seed": "4141004939",
"precision": "auto",
"iterations": 1,
"steps": 25,
"cfg_scale": 7.5,
"sampler_name": "k_lms",
"show_steps": false,
"use_init_img": false,
"use_inpainting": false,
"strength": 0.75,
"fit": true,
"prompt_structure_token_subject": "clouds ethereal mid-air by greg rutkowski and artgerm",
"prompt_structure_token_subject_enum": "custom",
"prompt_structure_token_framing": "",
"prompt_structure_token_framing_enum": "ecu",
"prompt_structure_token_position": "",
"prompt_structure_token_position_enum": "overhead",
"prompt_structure_token_film_type": "",
"prompt_structure_token_film_type_enum": "bw",
"prompt_structure_token_camera_settings": "",
"prompt_structure_token_camera_settings_enum": "high_speed",
"prompt_structure_token_shooting_context": "",
"prompt_structure_token_shooting_context_enum": "film_still",
"prompt_structure_token_lighting": "",
"prompt_structure_token_lighting_enum": "golden_hour",
"prompt_structure_token_subject_type": "",
"prompt_structure_token_subject_type_enum": "environment",
"prompt_structure_token_genre": "",
"prompt_structure_token_genre_enum": "fantasy",
"prompt": "clouds ethereal mid-air by greg rutkowski and artgerm, Environment concept art, Fantasy digital painting, trending on ArtStation [person dragon bird ocean buildings woman]"
}
================================================
FILE: engine/__init__.py
================================================
from .engine import *
from .node_tree import *
from .node_executor import *
from .node import *
from .nodes.input_nodes import *
from .nodes.pipeline_nodes import *
from .nodes.utility_nodes import *
from .nodes.annotation_nodes import *
from .annotations import openpose
from .annotations import ade20k
import bpy
import nodeitems_utils
class DreamTexturesNodeCategory(nodeitems_utils.NodeCategory):
@classmethod
def poll(cls, context):
return context.space_data.tree_type == DreamTexturesNodeTree.__name__
pipeline_items = [
nodeitems_utils.NodeItem(NodeStableDiffusion.bl_idname),
nodeitems_utils.NodeItem(NodeControlNet.bl_idname),
]
input_items = [
nodeitems_utils.NodeItem(NodeInteger.bl_idname),
nodeitems_utils.NodeItem(NodeString.bl_idname),
nodeitems_utils.NodeItem(NodeImage.bl_idname),
nodeitems_utils.NodeItem(NodeCollection.bl_idname),
nodeitems_utils.NodeItem(NodeRenderProperties.bl_idname),
]
if bpy.app.version >= (3, 5, 0):
input_items.append(nodeitems_utils.NodeItem(NodeImageFile.bl_idname))
utility_items = [
nodeitems_utils.NodeItem(NodeMath.bl_idname),
nodeitems_utils.NodeItem(NodeRandomValue.bl_idname),
nodeitems_utils.NodeItem(NodeRandomSeed.bl_idname),
nodeitems_utils.NodeItem(NodeSeed.bl_idname),
nodeitems_utils.NodeItem(NodeClamp.bl_idname),
nodeitems_utils.NodeItem(NodeFramePath.bl_idname),
nodeitems_utils.NodeItem(NodeCropImage.bl_idname),
nodeitems_utils.NodeItem(NodeJoinImages.bl_idname),
nodeitems_utils.NodeItem(NodeColorCorrect.bl_idname),
nodeitems_utils.NodeItem(NodeSeparateColor.bl_idname),
nodeitems_utils.NodeItem(NodeCombineColor.bl_idname),
nodeitems_utils.NodeItem(NodeSwitch.bl_idname),
nodeitems_utils.NodeItem(NodeCompare.bl_idname),
nodeitems_utils.NodeItem(NodeReplaceString.bl_idname),
]
if bpy.app.version >= (3, 5, 0):
utility_items.append(nodeitems_utils.NodeItem(NodeResizeImage.bl_idname))
annotations_items = [
nodeitems_utils.NodeItem(NodeAnnotationDepth.bl_idname),
nodeitems_utils.NodeItem(NodeAnnotationOpenPose.bl_idname),
nodeitems_utils.NodeItem(NodeAnnotationADE20K.bl_idname),
nodeitems_utils.NodeItem(NodeAnnotationViewport.bl_idname),
]
group_items = [
nodeitems_utils.NodeItem(bpy.types.NodeGroupOutput.__name__),
]
categories = [
DreamTexturesNodeCategory("DREAM_TEXTURES_PIPELINE", "Pipeline", items=pipeline_items),
DreamTexturesNodeCategory("DREAM_TEXTURES_INPUT", "Input", items=input_items),
DreamTexturesNodeCategory("DREAM_TEXTURES_UTILITY", "Utilities", items=utility_items),
DreamTexturesNodeCategory("DREAM_TEXTURES_ANNOTATIONS", "Annotations", items=annotations_items),
DreamTexturesNodeCategory("DREAM_TEXTURES_GROUP", "Group", items=group_items),
]
def register():
# Prompt
bpy.types.Scene.dream_textures_engine_prompt = bpy.props.PointerProperty(type=DreamPrompt)
# OpenPose
bpy.utils.register_class(openpose.ArmatureOpenPoseData)
bpy.types.Armature.dream_textures_openpose = bpy.props.PointerProperty(
type=openpose.ArmatureOpenPoseData
)
bpy.utils.register_class(openpose.BoneOpenPoseData)
bpy.types.Bone.dream_textures_openpose = bpy.props.PointerProperty(
type=openpose.BoneOpenPoseData
)
# ADE20K
bpy.utils.register_class(ade20k.ObjectADE20KData)
bpy.types.Object.dream_textures_ade20k = bpy.props.PointerProperty(
type=ade20k.ObjectADE20KData
)
bpy.utils.register_class(DreamTexturesNodeTree)
# Nodes
bpy.utils.register_class(NodeSocketControlNet)
bpy.utils.register_class(NodeStableDiffusion)
bpy.utils.register_class(NodeControlNet)
bpy.utils.register_class(NodeInteger)
bpy.utils.register_class(NodeString)
bpy.utils.register_class(NodeCollection)
bpy.utils.register_class(NodeImage)
bpy.utils.register_class(NodeImageFile)
bpy.utils.register_class(NodeRenderProperties)
bpy.utils.register_class(NodeAnnotationDepth)
bpy.utils.register_class(NodeAnnotationNormal)
bpy.utils.register_class(NodeAnnotationOpenPose)
bpy.utils.register_class(NodeAnnotationADE20K)
bpy.utils.register_class(NodeAnnotationViewport)
bpy.utils.register_class(NodeMath)
bpy.utils.register_class(NodeRandomValue)
bpy.utils.register_class(NodeRandomSeed)
bpy.utils.register_class(NodeSeed)
bpy.utils.register_class(NodeClamp)
bpy.utils.register_class(NodeFramePath)
bpy.utils.register_class(NodeCropImage)
bpy.utils.register_class(NodeResizeImage)
bpy.utils.register_class(NodeJoinImages)
bpy.utils.register_class(NodeColorCorrect)
bpy.utils.register_class(NodeSeparateColor)
bpy.utils.register_class(NodeCombineColor)
bpy.utils.register_class(NodeSwitch)
bpy.utils.register_class(NodeCompare)
bpy.utils.register_class(NodeReplaceString)
nodeitems_utils.register_node_categories("DREAM_TEXTURES_CATEGORIES", categories)
def unregister():
# OpenPose
del bpy.types.Armature.dream_textures_openpose
bpy.utils.unregister_class(openpose.ArmatureOpenPoseData)
del bpy.types.Bone.dream_textures_openpose
bpy.utils.unregister_class(openpose.BoneOpenPoseData)
# ADE20K
del bpy.types.Object.dream_textures_ade20k
bpy.utils.unregister_class(ade20k.ObjectADE20KData)
bpy.utils.unregister_class(DreamTexturesNodeTree)
# Nodes
bpy.utils.unregister_class(NodeSocketControlNet)
bpy.utils.unregister_class(NodeStableDiffusion)
bpy.utils.unregister_class(NodeControlNet)
bpy.utils.unregister_class(NodeInteger)
bpy.utils.unregister_class(NodeString)
bpy.utils.unregister_class(NodeCollection)
bpy.utils.unregister_class(NodeImage)
bpy.utils.unregister_class(NodeImageFile)
bpy.utils.unregister_class(NodeRenderProperties)
bpy.utils.unregister_class(NodeAnnotationDepth)
bpy.utils.unregister_class(NodeAnnotationNormal)
bpy.utils.unregister_class(NodeAnnotationOpenPose)
bpy.utils.unregister_class(NodeAnnotationADE20K)
bpy.utils.unregister_class(NodeAnnotationViewport)
bpy.utils.unregister_class(NodeMath)
bpy.utils.unregister_class(NodeRandomValue)
bpy.utils.unregister_class(NodeRandomSeed)
bpy.utils.unregister_class(NodeSeed)
bpy.utils.unregister_class(NodeClamp)
bpy.utils.unregister_class(NodeFramePath)
bpy.utils.unregister_class(NodeCropImage)
bpy.utils.unregister_class(NodeResizeImage)
bpy.utils.unregister_class(NodeJoinImages)
bpy.utils.unregister_class(NodeColorCorrect)
bpy.utils.unregister_class(NodeSeparateColor)
bpy.utils.unregister_class(NodeCombineColor)
bpy.utils.unregister_class(NodeSwitch)
bpy.utils.unregister_class(NodeCompare)
bpy.utils.unregister_class(NodeReplaceString)
nodeitems_utils.unregister_node_categories("DREAM_TEXTURES_CATEGORIES")
================================================
FILE: engine/annotations/ade20k.py
================================================
import bpy
import gpu
from gpu_extras.batch import batch_for_shader
import numpy as np
import threading
from .compat import UNIFORM_COLOR
annotation_enum_cases = [('91', 'airplane', 'airplane;aeroplane;plane'), ('127', 'animal', 'animal;animate;being;beast;brute;creature;fauna'), ('93', 'apparel', 'apparel;wearing;apparel;dress;clothes'), ('79', 'arcade machine', 'arcade;machine'), ('31', 'armchair', 'armchair'), ('139', 'ashcan', 'ashcan;trash;can;garbage;can;wastebin;ash;bin;ash-bin;ashbin;dustbin;trash;barrel;trash;bin'), ('87', 'awning', 'awning;sunshade;sunblind'), ('116', 'bag', 'bag'), ('120', 'ball', 'ball'), ('96', 'bannister', 'bannister;banister;balustrade;balusters;handrail'), ('78', 'bar', 'bar'), ('112', 'barrel', 'barrel;cask'), ('41', 'base', 'base;pedestal;stand'), ('113', 'basket', 'basket;handbasket'), ('38', 'bathtub', 'bathtub;bathing;tub;bath;tub'), ('8', 'bed', 'bed'), ('70', 'bench', 'bench'), ('128', 'bicycle', 'bicycle;bike;wheel;cycle'), ('132', 'blanket', 'blanket;cover'), ('64', 'blind', 'blind;screen'), ('77', 'boat', 'boat'), ('63', 'book', 'bookcase'), ('63', 'bookcase', 'bookcase'), ('89', 'booth', 'booth;cubicle;stall;kiosk'), ('99', 'bottle', 'bottle'), ('42', 'box', 'box'), ('62', 'bridge', 'bridge;span'), ('100', 'buffet', 'buffet;counter;sideboard'), ('2', 'building', 'building;edifice'), ('145', 'bulletin board', 'bulletin;board;notice;board'), ('81', 'bus', 'bus;autobus;coach;charabanc;double-decker;jitney;motorbus;motorcoach;omnibus;passenger;vehicle'), ('11', 'cabinet', 'cabinet'), ('107', 'canopy', 'canopy'), ('21', 'car', 'car;auto;automobile;machine;motorcar'), ('56', 'case', 'case;display;case;showcase;vitrine'), ('6', 'ceiling', 'ceiling'), ('20', 'chair', 'chair'), ('86', 'chandelier', 'chandelier;pendant;pendent'), ('45', 'chest of drawers', 'chest;of;drawers;chest;bureau;dresser'), ('149', 'clock', 'clock'), ('65', 'coffee table', 'coffee;table;cocktail;table'), ('43', 'column', 'column;pillar'), ('75', 'computer', 'computer;computing;machine;computing;device;data;processor;electronic;computer;information;processing;system'), ('106', 'conveyer belt', 'conveyer;belt;conveyor;belt;conveyer;conveyor;transporter'), ('46', 'counter', 'counter'), ('71', 'countertop', 'countertop'), ('118', 'cradle', 'cradle'), ('142', 'crt screen', 'crt;screen'), ('19', 'curtain', 'curtain;drape;drapery;mantle;pall'), ('40', 'cushion', 'cushion'), ('34', 'desk', 'desk'), ('92', 'dirt track', 'dirt;track'), ('130', 'dishwasher', 'dishwasher;dish;washer;dishwashing;machine'), ('15', 'door', 'door;double;door'), ('14', 'earth', 'earth;ground'), ('97', 'escalator', 'escalator;moving;staircase;moving;stairway'), ('140', 'fan', 'fan'), ('33', 'fence', 'fence;fencing'), ('30', 'field', 'field'), ('50', 'fireplace', 'fireplace;hearth;open;fireplace'), ('150', 'flag', 'flag'), ('4', 'floor', 'floor;flooring'), ('67', 'flower', 'flower'), ('121', 'food', 'food;solid;food'), ('105', 'fountain', 'fountain'), ('148', 'glass', 'glass;drinking;glass'), ('52', 'grandstand', 'grandstand;covered;stand'), ('10', 'grass', 'grass'), ('69', 'hill', 'hill'), ('134', 'hood', 'hood;exhaust;hood'), ('26', 'house', 'house'), ('80', 'hovel', 'hovel;hut;hutch;shack;shanty'), ('74', 'land', 'kitchen;island'), ('74', 'kitchen island', 'kitchen;island'), ('129', 'lake', 'lake'), ('37', 'lamp', 'lamp'), ('83', 'light', 'light;light;source'), ('125', 'microwave', 'microwave;microwave;oven'), ('117', 'minibike', 'minibike;motorbike'), ('28', 'mirror', 'mirror'), ('144', 'monitor', 'monitor;monitoring;device'), ('17', 'mountain', 'mountain;mount'), ('98', 'ottoman', 'ottoman;pouf;pouffe;puff;hassock'), ('119', 'oven', 'oven'), ('23', 'painting', 'painting;picture'), ('73', 'palm', 'palm;palm;tree'), ('53', 'path', 'path'), ('13', 'person', 'person;individual;someone;somebody;mortal;soul'), ('141', 'pier', 'pier;wharf;wharfage;dock'), ('58', 'pillow', 'pillow'), ('18', 'plant', 'plant;flora;plant;life'), ('143', 'plate', 'plate'), ('109', 'plaything', 'plaything;toy'), ('94', 'pole', 'pole'), ('57', 'pool table', 'pool;table;billiard;table;snooker;table'), ('101', 'poster', 'poster;posting;placard;notice;bill;card'), ('147', 'radiator', 'radiator'), ('39', 'railing', 'railing;rail'), ('51', 'refrigerator', 'refrigerator;icebox'), ('61', 'river', 'river'), ('7', 'road', 'road;route'), ('35', 'rock', 'rock;stone'), ('29', 'rug', 'rug;carpet;carpeting'), ('55', 'runway', 'runway'), ('47', 'sand', 'sand'), ('135', 'sconce', 'sconce'), ('59', 'screen door', 'screen;door;screen'), ('59', 'screen', 'screen;door;screen'), ('133', 'sculpture', 'sculpture'), ('27', 'sea', 'sea'), ('32', 'seat', 'seat'), ('25', 'shelf', 'shelf'), ('104', 'ship', 'ship'), ('146', 'shower', 'shower'), ('12', 'sidewalk', 'sidewalk;pavement'), ('44', 'signboard', 'signboard;sign'), ('48', 'sink', 'sink'), ('3', 'sky', 'sky'), ('49', 'skyscraper', 'skyscraper'), ('24', 'sofa', 'sofa;couch;lounge'), ('102', 'stage', 'stage'), ('54', 'step', 'stairs;steps'), ('54', 'stairs', 'stairs;steps'), ('60', 'stairway', 'stairway;staircase'), ('72', 'stove', 'stove;kitchen;stove;range;kitchen;range;cooking;stove'), ('88', 'streetlight', 'streetlight;street;lamp'), ('110', 'swimming pool', 'swimming;pool;swimming;bath;natatorium'), ('76', 'swivel chair', 'swivel;chair'), ('16', 'table', 'table'), ('123', 'tank', 'tank;storage;tank'), ('90', 'television receiver', 'television;television;receiver;television;set;tv;tv;set;idiot;box;boob;tube;telly;goggle;box'), ('115', 'tent', 'tent;collapsible;shelter'), ('66', 'stool', 'toilet;can;commode;crapper;pot;potty;stool;throne'), ('66', 'pot', 'toilet;can;commode;crapper;pot;potty;stool;throne'), ('66', 'toilet', 'toilet;can;commode;crapper;pot;potty;stool;throne'), ('82', 'towel', 'towel'), ('85', 'tower', 'tower'), ('124', 'trade name', 'trade;name;brand;name;brand;marque'), ('137', 'traffic light', 'traffic;light;traffic;signal;stoplight'), ('138', 'tray', 'tray'), ('5', 'tree', 'tree'), ('84', 'truck', 'truck;motortruck'), ('103', 'van', 'van'), ('136', 'vase', 'vase'), ('1', 'wall', 'wall'), ('36', 'wardrobe', 'wardrobe;closet;press'), ('108', 'washer', 'washer;automatic;washer;washing;machine'), ('22', 'water', 'water'), ('114', 'waterfall', 'waterfall;falls'), ('9', 'windowpane', 'windowpane;window')]
annotation_colors = {'80': (1.0, 0.0, 0.996078431372549, 1.0), '140': (0.00392156862745098, 0.9607843137254902, 1.0, 1.0), '115': (0.43529411764705883, 0.8784313725490196, 0.996078431372549, 1.0), '33': (1.0, 0.7215686274509804, 0.023529411764705882, 1.0), '77': (0.6784313725490196, 1.0, 0.0, 1.0), '58': (0.0, 0.9215686274509803, 1.0, 1.0), '98': (0.996078431372549, 0.6, 0.0, 1.0), '74': (0.0, 1.0, 0.1607843137254902, 1.0), '150': (0.3568627450980392, 0.0, 0.996078431372549, 1.0), '117': (0.6431372549019608, 0.0, 1.0, 1.0), '18': (0.8, 1.0, 0.01568627450980392, 1.0), '145': (0.7215686274509804, 1.0, 0.0, 1.0), '63': (0.0, 1.0, 0.9607843137254902, 1.0), '9': (0.9019607843137255, 0.9019607843137255, 0.9019607843137255, 1.0), '34': (0.0392156862745098, 1.0, 0.2784313725490196, 1.0), '120': (1.0, 0.00392156862745098, 0.6352941176470588, 1.0), '61': (0.0392156862745098, 0.7843137254901961, 0.7843137254901961, 1.0), '32': (0.027450980392156862, 0.996078431372549, 0.8745098039215686, 1.0), '124': (0.5215686274509804, 0.996078431372549, 0.0, 1.0), '6': (0.4666666666666667, 0.47058823529411764, 0.3137254901960784, 1.0), '104': (1.0, 0.9215686274509803, 0.0, 1.0), '38': (0.4, 0.03137254901960784, 1.0, 1.0), '106': (0.5215686274509804, 0.0, 1.0, 1.0), '56': (0.00392156862745098, 0.0, 0.996078431372549, 1.0), '12': (0.9215686274509803, 1.0, 0.027450980392156862, 1.0), '19': (1.0, 0.2, 0.03137254901960784, 1.0), '70': (0.7607843137254902, 1.0, 0.00392156862745098, 1.0), '88': (0.00392156862745098, 0.2784313725490196, 1.0, 1.0), '62': (1.0, 0.3254901960784314, 0.00392156862745098, 1.0), '7': (0.5490196078431373, 0.5490196078431373, 0.5490196078431373, 1.0), '29': (1.0, 0.03529411764705882, 0.3607843137254902, 1.0), '82': (1.0, 0.0, 0.4, 1.0), '142': (0.47843137254901963, 0.00392156862745098, 1.0, 1.0), '11': (0.8784313725490196, 0.0196078431372549, 1.0, 1.0), '147': (1.0, 0.8392156862745098, 0.00784313725490196, 1.0), '76': (0.0392156862745098, 0.0, 1.0, 1.0), '146': (0.0, 0.5215686274509804, 0.996078431372549, 1.0), '54': (1.0, 0.8784313725490196, 0.00392156862745098, 1.0), '94': (0.2, 0.0, 1.0, 1.0), '59': (0.0, 0.8, 1.0, 1.0), '118': (0.6039215686274509, 0.0, 1.0, 1.0), '39': (1.0, 0.24313725490196078, 0.027450980392156862, 1.0), '101': (0.5607843137254902, 0.996078431372549, 0.00392156862745098, 1.0), '46': (0.9254901960784314, 0.043137254901960784, 1.0, 1.0), '110': (0.0, 0.7215686274509804, 1.0, 1.0), '45': (0.023529411764705882, 0.2, 1.0, 1.0), '93': (0.0, 0.44313725490196076, 0.996078431372549, 1.0), '13': (0.5882352941176471, 0.0196078431372549, 0.24313725490196078, 1.0), '50': (0.9803921568627451, 0.03529411764705882, 0.058823529411764705, 1.0), '64': (0.00392156862745098, 0.23921568627450981, 1.0, 1.0), '30': (0.43529411764705883, 0.03529411764705882, 1.0, 1.0), '99': (0.0, 1.0, 0.043137254901960784, 1.0), '35': (1.0, 0.1568627450980392, 0.03529411764705882, 1.0), '125': (0.996078431372549, 0.0, 0.9176470588235294, 1.0), '105': (0.03137254901960784, 0.7215686274509804, 0.6705882352941176, 1.0), '135': (0.0, 0.1607843137254902, 1.0, 1.0), '53': (1.0, 0.11764705882352941, 0.0, 1.0), '66': (0.0, 1.0, 0.5215686274509804, 1.0), '8': (0.8, 0.0196078431372549, 0.996078431372549, 1.0), '26': (1.0, 0.03137254901960784, 0.8666666666666667, 1.0), '14': (0.47058823529411764, 0.47058823529411764, 0.27450980392156865, 1.0), '73': (0.0, 0.3215686274509804, 0.996078431372549, 1.0), '23': (1.0, 0.023529411764705882, 0.2, 1.0), '24': (0.043137254901960784, 0.4, 1.0, 1.0), '97': (0.0, 1.0, 0.6392156862745098, 1.0), '132': (0.0784313725490196, 0.0, 1.0, 1.0), '100': (1.0, 0.4392156862745098, 0.0, 1.0), '83': (1.0, 0.6784313725490196, 0.00392156862745098, 1.0), '85': (0.996078431372549, 0.7215686274509804, 0.7215686274509804, 1.0), '79': (1.0, 0.3607843137254902, 0.0, 1.0), '144': (0.0, 0.3607843137254902, 1.0, 1.0), '113': (0.3568627450980392, 1.0, 0.0, 1.0), '133': (1.0, 1.0, 0.0, 1.0), '52': (0.12156862745098039, 1.0, 0.0, 1.0), '28': (0.8627450980392157, 0.8627450980392157, 0.8627450980392157, 1.0), '10': (0.0196078431372549, 0.9803921568627451, 0.027450980392156862, 1.0), '2': (0.7058823529411765, 0.47058823529411764, 0.47058823529411764, 1.0), '103': (0.6392156862745098, 0.996078431372549, 0.0, 1.0), '91': (0.00392156862745098, 0.996078431372549, 0.3254901960784314, 1.0), '121': (1.0, 0.8, 0.0, 1.0), '86': (0.0, 0.12156862745098039, 0.996078431372549, 1.0), '27': (0.03529411764705882, 0.027450980392156862, 0.9058823529411765, 1.0), '114': (0.0, 0.8823529411764706, 1.0, 1.0), '20': (0.796078431372549, 0.27450980392156865, 0.011764705882352941, 1.0), '134': (0.0, 0.6, 1.0, 1.0), '17': (0.5568627450980392, 1.0, 0.5450980392156862, 1.0), '3': (0.023529411764705882, 0.9019607843137255, 0.9019607843137255, 1.0), '65': (0.00392156862745098, 0.996078431372549, 0.4392156862745098, 1.0), '139': (0.6823529411764706, 0.0, 1.0, 1.0), '130': (0.8392156862745098, 1.0, 0.0, 1.0), '136': (0.00392156862745098, 1.0, 0.803921568627451, 1.0), '51': (0.0784313725490196, 1.0, 0.0, 1.0), '15': (0.03137254901960784, 1.0, 0.20392156862745098, 1.0), '55': (0.6, 1.0, 0.0, 1.0), '5': (0.01568627450980392, 0.7843137254901961, 0.023529411764705882, 1.0), '22': (0.23921568627450981, 0.9019607843137255, 0.984313725490196, 1.0), '72': (0.2, 1.0, 0.0, 1.0), '41': (1.0, 0.4823529411764706, 0.0392156862745098, 1.0), '137': (0.1607843137254902, 0.0, 1.0, 1.0), '92': (0.0, 0.0392156862745098, 1.0, 1.0), '21': (0.0, 0.4, 0.7843137254901961, 1.0), '109': (1.0, 0.0, 0.11764705882352941, 1.0), '1': (0.47058823529411764, 0.47058823529411764, 0.47058823529411764, 1.0), '67': (1.0, 0.00392156862745098, 0.011764705882352941, 1.0), '60': (0.12156862745098039, 0.0, 0.996078431372549, 1.0), '44': (1.0, 0.0196078431372549, 0.6039215686274509, 1.0), '69': (1.0, 0.4, 0.0, 1.0), '107': (0.0, 0.996078431372549, 0.36470588235294116, 1.0), '4': (0.3137254901960784, 0.19607843137254902, 0.20392156862745098, 1.0), '90': (0.0, 1.0, 0.7647058823529411, 1.0), '149': (0.396078431372549, 1.0, 0.0, 1.0), '129': (0.0392156862745098, 0.7490196078431373, 0.8313725490196079, 1.0), '75': (0.0, 1.0, 0.6784313725490196, 1.0), '141': (0.2823529411764706, 0.0, 1.0, 1.0), '128': (1.0, 0.9607843137254902, 0.0, 1.0), '57': (1.0, 0.2784313725490196, 0.0, 1.0), '49': (0.5490196078431373, 0.5490196078431373, 0.5490196078431373, 1.0), '108': (0.7215686274509804, 0.0, 0.996078431372549, 1.0), '87': (0.0, 1.0, 0.23921568627450981, 1.0), '43': (1.0, 0.03137254901960784, 0.16470588235294117, 1.0), '71': (0.0, 0.5607843137254902, 1.0, 1.0), '31': (0.03529411764705882, 0.996078431372549, 0.8352941176470589, 1.0), '81': (1.0, 0.0, 0.9568627450980393, 1.0), '36': (0.027450980392156862, 1.0, 1.0, 1.0), '143': (0.0, 1.0, 0.7254901960784313, 1.0), '148': (0.09411764705882353, 0.7607843137254902, 0.7607843137254902, 1.0), '102': (0.3215686274509804, 0.0, 1.0, 1.0), '84': (1.0, 0.0, 0.08235294117647059, 1.0), '47': (0.6274509803921569, 0.5882352941176471, 0.07450980392156863, 1.0), '127': (1.0, 0.0, 0.47843137254901963, 1.0), '16': (0.996078431372549, 0.023529411764705882, 0.3215686274509804, 1.0), '78': (0.0, 0.996078431372549, 0.6078431372549019, 1.0), '25': (1.0, 0.023529411764705882, 0.27450980392156865, 1.0), '138': (0.16862745098039217, 0.996078431372549, 0.011764705882352941, 1.0), '42': (0.00392156862745098, 1.0, 0.07450980392156863, 1.0), '119': (0.2784313725490196, 1.0, 0.00392156862745098, 1.0), '112': (0.996078431372549, 0.0, 0.4392156862745098, 1.0), '89': (0.996078431372549, 0.0, 0.796078431372549, 1.0), '96': (0.0, 0.47843137254901963, 1.0, 1.0), '37': (0.8823529411764706, 1.0, 0.03529411764705882, 1.0), '48': (0.0, 0.6392156862745098, 0.996078431372549, 1.0), '116': (0.27058823529411763, 0.7176470588235294, 0.6196078431372549, 1.0), '40': (1.0, 0.7607843137254902, 0.027450980392156862, 1.0), '123': (0.0, 1.0, 0.9176470588235294, 1.0)}
def annotation_update(self, context):
self.color = annotation_colors[self.annotation][:3]
class ObjectADE20KData(bpy.types.PropertyGroup):
bl_label = "ADE20K Segmentation"
bl_idname = "dream_textures.ObjectADE20KData"
enabled: bpy.props.BoolProperty(name="Enabled", default=False)
annotation: bpy.props.EnumProperty(
name="Class",
items=annotation_enum_cases,
update=annotation_update
)
# for visualization only
color: bpy.props.FloatVectorProperty(name="", subtype='COLOR', default=annotation_colors[annotation_enum_cases[0][0]][:3])
def render_ade20k_map(context, collection=None, invert=True):
e = threading.Event()
result = None
def _execute():
nonlocal result
width, height = context.scene.render.resolution_x, context.scene.render.resolution_y
matrix = context.scene.camera.matrix_world.inverted()
projection_matrix = context.scene.camera.calc_matrix_camera(
context,
x=width,
y=height
)
offscreen = gpu.types.GPUOffScreen(width, height)
with offscreen.bind():
fb = gpu.state.active_framebuffer_get()
fb.clear(color=(0.0, 0.0, 0.0, 0.0), depth=1)
gpu.state.depth_test_set('LESS_EQUAL')
gpu.state.depth_mask_set(True)
with gpu.matrix.push_pop():
gpu.matrix.load_matrix(matrix)
gpu.matrix.load_projection_matrix(projection_matrix)
def render_mesh(mesh, transform, color):
mesh.transform(transform)
mesh.calc_loop_triangles()
vertices = np.empty((len(mesh.vertices), 3), 'f')
indices = np.empty((len(mesh.loop_triangles), 3), 'i')
mesh.vertices.foreach_get("co", np.reshape(vertices, len(mesh.vertices) * 3))
mesh.loop_triangles.foreach_get("vertices", np.reshape(indices, len(mesh.loop_triangles) * 3))
draw_annotation(vertices, indices, color)
if collection is None:
for object in context.object_instances:
if not hasattr(object.object, 'dream_textures_ade20k') or not object.object.dream_textures_ade20k.enabled:
continue
try:
mesh = object.object.to_mesh()
if mesh is not None:
render_mesh(mesh, object.matrix_world, annotation_colors[object.object.dream_textures_ade20k.annotation])
object.object.to_mesh_clear()
except:
continue
else:
for object in collection.objects:
if not hasattr(object, 'dream_textures_ade20k') or not object.dream_textures_ade20k.enabled:
continue
try:
mesh = object.to_mesh(depsgraph=context)
if mesh is not None:
render_mesh(mesh, object.matrix_world, annotation_colors[object.dream_textures_ade20k.annotation])
object.to_mesh_clear()
except:
continue
result = np.array(fb.read_color(0, 0, width, height, 4, 0, 'FLOAT').to_list())
result[:, :, 3] = 1
gpu.state.depth_test_set('NONE')
offscreen.free()
e.set()
if threading.current_thread() == threading.main_thread():
_execute()
return result
else:
bpy.app.timers.register(_execute, first_interval=0)
e.wait()
return result
def draw_annotation(vertices, indices, color):
shader = gpu.shader.from_builtin(UNIFORM_COLOR)
batch = batch_for_shader(
shader, 'TRIS',
{"pos": vertices},
indices=indices,
)
shader.bind()
shader.uniform_float("color", color)
batch.draw(shader)
================================================
FILE: engine/annotations/compat.py
================================================
import bpy
UNIFORM_COLOR = 'UNIFORM_COLOR' if bpy.app.version >= (3, 4, 0) else '3D_UNIFORM_COLOR'
"""
2D_ and 3D_ prefixed built-in shaders were deprecated in Blender 3.4 and removed in Blender 4.0
"""
================================================
FILE: engine/annotations/depth.py
================================================
import bpy
import gpu
from gpu_extras.batch import batch_for_shader
import numpy as np
import threading
from .compat import UNIFORM_COLOR
def render_depth_map(context, collection=None, invert=True, width=None, height=None, matrix=None, projection_matrix=None, main_thread=False):
e = threading.Event()
result = None
width, height = width or context.scene.render.resolution_x, height or context.scene.render.resolution_y
matrix = matrix or context.scene.camera.matrix_world.inverted()
projection_matrix = projection_matrix or context.scene.camera.calc_matrix_camera(
context,
x=width,
y=height
)
def _execute():
nonlocal result
offscreen = gpu.types.GPUOffScreen(width, height)
with offscreen.bind():
fb = gpu.state.active_framebuffer_get()
fb.clear(color=(0.0, 0.0, 0.0, 0.0), depth=1)
gpu.state.depth_test_set('LESS_EQUAL')
gpu.state.depth_mask_set(True)
with gpu.matrix.push_pop():
gpu.matrix.load_matrix(matrix)
gpu.matrix.load_projection_matrix(projection_matrix)
shader = gpu.shader.from_builtin(UNIFORM_COLOR)
def render_mesh(mesh, transform):
mesh.transform(transform)
mesh.calc_loop_triangles()
vertices = np.empty((len(mesh.vertices), 3), 'f')
indices = np.empty((len(mesh.loop_triangles), 3), 'i')
mesh.vertices.foreach_get("co", np.reshape(vertices, len(mesh.vertices) * 3))
mesh.loop_triangles.foreach_get("vertices", np.reshape(indices, len(mesh.loop_triangles) * 3))
batch = batch_for_shader(
shader, 'TRIS',
{"pos": vertices},
indices=indices,
)
batch.draw(shader)
if collection is None:
for object in context.object_instances:
try:
mesh = object.object.to_mesh()
if mesh is not None:
render_mesh(mesh, object.matrix_world)
object.object.to_mesh_clear()
except:
continue
else:
for object in collection.objects:
try:
mesh = object.to_mesh(depsgraph=context)
if mesh is not None:
render_mesh(mesh, object.matrix_world)
object.to_mesh_clear()
except:
continue
depth = np.array(fb.read_depth(0, 0, width, height).to_list())
if invert:
depth = 1 - depth
mask = np.array(fb.read_color(0, 0, width, height, 4, 0, 'UBYTE').to_list())[:, :, 3]
depth *= mask
depth = np.interp(depth, [np.ma.masked_equal(depth, 0, copy=False).min(), depth.max()], [0, 1]).clip(0, 1)
gpu.state.depth_test_set('NONE')
offscreen.free()
result = depth
e.set()
if main_thread or threading.current_thread() == threading.main_thread():
_execute()
return result
else:
bpy.app.timers.register(_execute, first_interval=0)
e.wait()
return result
================================================
FILE: engine/annotations/normal.py
================================================
import bpy
import gpu
from gpu_extras.batch import batch_for_shader
import bmesh
import numpy as np
import threading
def render_normal_map(context, collection=None, width=None, height=None, matrix=None, projection_matrix=None, main_thread=False):
e = threading.Event()
result = None
width, height = width or context.scene.render.resolution_x, height or context.scene.render.resolution_y
matrix = matrix or context.scene.camera.matrix_world.inverted()
projection_matrix = projection_matrix or context.scene.camera.calc_matrix_camera(
context,
x=width,
y=height
)
def normals_shader(smooth):
vert_out = gpu.types.GPUStageInterfaceInfo("my_interface")
if smooth:
vert_out.smooth('VEC3', "color")
else:
vert_out.flat('VEC3', "color")
shader_info = gpu.types.GPUShaderCreateInfo()
shader_info.push_constant('MAT4', "ModelViewProjectionMatrix")
shader_info.push_constant('MAT4', "ModelViewMatrix")
shader_info.vertex_in(0, 'VEC3', "position")
shader_info.vertex_in(1, 'VEC3', "normal")
shader_info.vertex_out(vert_out)
shader_info.fragment_out(0, 'VEC4', "fragColor")
shader_info.vertex_source("""
void main()
{
gl_Position = ModelViewProjectionMatrix * vec4(position, 1.0f);
color = normalize(mat3(ModelViewMatrix) * normal);
}
""")
shader_info.fragment_source("""
void main()
{
vec4 c = vec4((color + 1) / 2, 1.0f);
fragColor = vec4(1 - c.r, c.g, c.b, c.a);
}
""")
return gpu.shader.create_from_info(shader_info)
def _execute():
nonlocal result
offscreen = gpu.types.GPUOffScreen(width, height)
with offscreen.bind():
fb = gpu.state.active_framebuffer_get()
fb.clear(color=(0.5, 0.5, 1.0, 1.0), depth=1)
gpu.state.depth_test_set('LESS_EQUAL')
gpu.state.depth_mask_set(True)
with gpu.matrix.push_pop():
gpu.matrix.load_matrix(matrix)
gpu.matrix.load_projection_matrix(projection_matrix)
def render_mesh(mesh, transform):
smooth_shader = normals_shader(smooth=True)
smooth_shader.uniform_float("ModelViewMatrix", gpu.matrix.get_model_view_matrix())
flat_shader = normals_shader(smooth=False)
flat_shader.uniform_float("ModelViewMatrix", gpu.matrix.get_model_view_matrix())
mesh.transform(transform)
bm = bmesh.new()
bm.from_mesh(mesh)
smooth_mesh = bm.copy()
flat_mesh = bm.copy()
bmesh.ops.delete(smooth_mesh, geom=[f for f in smooth_mesh.faces if not f.smooth], context='FACES')
bmesh.ops.delete(flat_mesh, geom=[f for f in flat_mesh.faces if f.smooth], context='FACES')
def draw(mesh, smooth):
vertices = [v.co for v in mesh.verts]
normals = [v.normal for v in mesh.verts]
indices = [[loop.vert.index for loop in looptris] for looptris in mesh.calc_loop_triangles()]
shader = smooth_shader if smooth else flat_shader
shader.bind()
batch = batch_for_shader(
shader, 'TRIS',
{"position": vertices, "normal": normals},
indices=indices,
)
batch.draw(shader)
if len(smooth_mesh.verts) > 0:
draw(smooth_mesh, smooth=True)
if len(flat_mesh.verts) > 0:
draw(flat_mesh, smooth=False)
if collection is None:
for object in context.object_instances:
try:
mesh = object.object.to_mesh()
if mesh is not None:
render_mesh(mesh, object.matrix_world)
object.object.to_mesh_clear()
except:
continue
else:
for object in collection.objects:
try:
mesh = object.to_mesh(depsgraph=context)
if mesh is not None:
render_mesh(mesh, object.matrix_world)
object.to_mesh_clear()
except:
continue
normal_map = np.array(fb.read_color(0, 0, width, height, 4, 0, 'FLOAT').to_list())
gpu.state.depth_test_set('NONE')
offscreen.free()
result = normal_map
e.set()
if main_thread or threading.current_thread() == threading.main_thread():
_execute()
return result
else:
bpy.app.timers.register(_execute, first_interval=0)
e.wait()
return result
================================================
FILE: engine/annotations/openpose.py
================================================
import bpy
import bpy_extras
import gpu
from gpu_extras.batch import batch_for_shader
import mathutils
import numpy as np
import enum
import math
import threading
from .compat import UNIFORM_COLOR
class Side(enum.IntEnum):
HEAD = 0
TAIL = 1
class Bone(enum.IntEnum):
NOSE = 0
CHEST = 1
SHOULDER_L = 2
SHOULDER_R = 3
ELBOW_L = 4
ELBOW_R = 5
HAND_L = 6
HAND_R = 7
HIP_L = 8
HIP_R = 9
KNEE_L = 10
KNEE_R = 11
FOOT_L = 12
FOOT_R = 13
EYE_L = 14
EYE_R = 15
EAR_L = 16
EAR_R = 17
def identify(self, armature, pose):
if not getattr(armature.dream_textures_openpose, self.name):
return None, None
for bone in pose.bones:
if bone.bone.dream_textures_openpose.enabled:
if bone.bone.dream_textures_openpose.bone == str(self.value):
return bone, Side(int(bone.bone.dream_textures_openpose.side))
options = self.name_detection_options()
for option in options:
if (result := pose.bones.get(option[0], None)) is not None:
return result, option[1]
return None, None
def name_detection_options(self):
match self:
case Bone.NOSE:
return [('nose_master', Side.TAIL), ('nose.001', Side.TAIL), ('Head', Side.TAIL)]
case Bone.CHEST:
return [('spine_fk.003', Side.TAIL), ('spine.003', Side.TAIL), ('Spine4', Side.TAIL)]
case Bone.SHOULDER_L:
return [('shoulder_ik.L', Side.TAIL), ('shoulder.L', Side.TAIL), ('LeftShoulder', Side.TAIL)]
case Bone.SHOULDER_R:
return [('shoulder_ik.R', Side.TAIL), ('shoulder.R', Side.TAIL), ('RightShoulder', Side.TAIL)]
case Bone.ELBOW_L:
return [('upper_arm_ik.L', Side.TAIL), ('upper_arm.L', Side.TAIL), ('LeftArm', Side.TAIL)]
case Bone.ELBOW_R:
return [('upper_arm_ik.R', Side.TAIL), ('upper_arm.R', Side.TAIL), ('RightArm', Side.TAIL)]
case Bone.HAND_L:
return [('hand_ik.L', Side.TAIL), ('forearm.L', Side.TAIL), ('LeftForeArm', Side.TAIL)]
case Bone.HAND_R:
return [('hand_ik.R', Side.TAIL), ('forearm.R', Side.TAIL), ('RightForeArm', Side.TAIL)]
case Bone.HIP_L:
return [('thigh_ik.L', Side.HEAD), ('thigh.L', Side.HEAD), ('LeftThigh', Side.HEAD)]
case Bone.HIP_R:
return [('thigh_ik.R', Side.HEAD), ('thigh.R', Side.HEAD), ('RightThigh', Side.HEAD)]
case Bone.KNEE_L:
return [('thigh_ik.L', Side.TAIL), ('thigh.L', Side.TAIL), ('LeftShin', Side.HEAD)]
case Bone.KNEE_R:
return [('thigh_ik.R', Side.TAIL), ('thigh.R', Side.TAIL), ('RightShin', Side.HEAD)]
case Bone.FOOT_L:
return [('foot_ik.L', Side.TAIL), ('shin.L', Side.TAIL), ('LeftFoot', Side.HEAD)]
case Bone.FOOT_R:
return [('foot_ik.R', Side.TAIL), ('shin.R', Side.TAIL), ('RightFoot', Side.HEAD)]
case Bone.EYE_L:
return [('master_eye.L', Side.TAIL), ('eye.L', Side.TAIL)]
case Bone.EYE_R:
return [('master_eye.R', Side.TAIL), ('eye.R', Side.TAIL)]
case Bone.EAR_L:
return [('ear.L', Side.TAIL), ('ear.L.001', Side.TAIL)]
case Bone.EAR_R:
return [('ear.R', Side.TAIL), ('ear.R.001', Side.TAIL)]
def color(self):
match self:
case Bone.NOSE: return (255, 0, 0)
case Bone.CHEST: return (255, 85, 0)
case Bone.SHOULDER_L: return (85, 255, 0)
case Bone.SHOULDER_R: return (255, 170, 0)
case Bone.ELBOW_L: return (0, 255, 0)
case Bone.ELBOW_R: return (255, 255, 0)
case Bone.HAND_L: return (0, 255, 85)
case Bone.HAND_R: return (170, 255, 0)
case Bone.HIP_L: return (0, 85, 255)
case Bone.HIP_R: return (0, 255, 170)
case Bone.KNEE_L: return (0, 0, 255)
case Bone.KNEE_R: return (0, 255, 255)
case Bone.FOOT_L: return (85, 0, 255)
case Bone.FOOT_R: return (0, 170, 255)
case Bone.EYE_L: return (255, 0, 255)
case Bone.EYE_R: return (170, 0, 255)
case Bone.EAR_L: return (255, 0, 85)
case Bone.EAR_R: return (255, 0, 170)
openpose_bones = ((str(b.value), b.name.title(), '') for b in Bone)
openpose_sides = ((str(s.value), s.name.title(), '') for s in Side)
class BoneOpenPoseData(bpy.types.PropertyGroup):
bl_label = "OpenPose"
bl_idname = "dream_textures.BoneOpenPoseData"
enabled: bpy.props.BoolProperty(name="Enabled", default=False)
bone: bpy.props.EnumProperty(
name="OpenPose Bone",
items=openpose_bones
)
side: bpy.props.EnumProperty(
name="Bone Side",
items=openpose_sides
)
ArmatureOpenPoseData = type('ArmatureOpenPoseData', (bpy.types.PropertyGroup,), {
"bl_label": "OpenPose",
"bl_idname": "dream_textures.ArmatureOpenPoseData",
"__annotations__": { b.name: bpy.props.BoolProperty(name=b.name.title(), default=True) for b in Bone },
})
def render_openpose_map(context, collection=None):
e = threading.Event()
result = None
def _execute():
nonlocal result
width, height = context.scene.render.resolution_x, context.scene.render.resolution_y
offscreen = gpu.types.GPUOffScreen(width, height)
with offscreen.bind():
fb = gpu.state.active_framebuffer_get()
fb.clear(color=(0.0, 0.0, 0.0, 0.0), depth=1)
gpu.state.depth_test_set('LESS_EQUAL')
gpu.state.depth_mask_set(True)
lines = {
(Bone.NOSE, Bone.CHEST): (0, 0, 255),
(Bone.CHEST, Bone.SHOULDER_L): (255, 85, 0),
(Bone.CHEST, Bone.SHOULDER_R): (255, 0, 0),
(Bone.SHOULDER_L, Bone.ELBOW_L): (170, 255, 0),
(Bone.SHOULDER_R, Bone.ELBOW_R): (255, 170, 0),
(Bone.ELBOW_L, Bone.HAND_L): (85, 255, 0),
(Bone.ELBOW_R, Bone.HAND_R): (255, 255, 0),
(Bone.CHEST, Bone.HIP_L): (0, 255, 255),
(Bone.CHEST, Bone.HIP_R): (0, 255, 0),
(Bone.HIP_L, Bone.KNEE_L): (0, 170, 255),
(Bone.HIP_R, Bone.KNEE_R): (0, 255, 85),
(Bone.KNEE_L, Bone.FOOT_L): (0, 85, 255),
(Bone.KNEE_R, Bone.FOOT_R): (0, 255, 170),
(Bone.NOSE, Bone.EYE_L): (255, 0, 255),
(Bone.NOSE, Bone.EYE_R): (85, 0, 255),
(Bone.EYE_L, Bone.EAR_L): (255, 0, 170),
(Bone.EYE_R, Bone.EAR_R): (170, 0, 255),
}
with gpu.matrix.push_pop():
ratio = width / height
projection_matrix = mathutils.Matrix((
(1 / ratio, 0, 0, 0),
(0, 1, 0, 0),
(0, 0, -1, 0),
(0, 0, 0, 1)
))
gpu.matrix.load_matrix(mathutils.Matrix.Identity(4))
gpu.matrix.load_projection_matrix(projection_matrix)
gpu.state.blend_set('ALPHA')
def transform(x, y):
return (
(x - 0.5) * 2 * ratio,
(y - 0.5) * 2
)
shader = gpu.shader.from_builtin(UNIFORM_COLOR)
batch = batch_for_shader(shader, 'TRI_STRIP', {"pos": [(-ratio, -1, 0), (-ratio, 1, 0), (ratio, -1, 0), (ratio, 1, 0)]})
shader.bind()
shader.uniform_float("color", (0, 0, 0, 1))
batch.draw(shader)
for object in (context.scene.objects if collection is None else collection.objects):
object = object.evaluated_get(context)
if object.hide_render:
continue
if object.pose is None:
continue
for connection, color in lines.items():
a, a_side = connection[0].identify(object.data, object.pose)
b, b_side = connection[1].identify(object.data, object.pose)
if a is None or b is None:
continue
a = bpy_extras.object_utils.world_to_camera_view(context.scene, context.scene.camera, object.matrix_world @ (a.tail if a_side == Side.TAIL else a.head))
b = bpy_extras.object_utils.world_to_camera_view(context.scene, context.scene.camera, object.matrix_world @ (b.tail if b_side == Side.TAIL else b.head))
draw_ellipse_2d(transform(a[0], a[1]), transform(b[0], b[1]), .015, 32, (color[0] / 255.0, color[1] / 255.0, color[2] / 255.0, 0.5))
for b in Bone:
bone, side = b.identify(object.data, object.pose)
color = b.color()
if bone is None: continue
tail = bpy_extras.object_utils.world_to_camera_view(context.scene, context.scene.camera, object.matrix_world @ (bone.tail if side == Side.TAIL else bone.head))
draw_circle_2d(transform(tail[0], tail[1]), .015, 16, (color[0] / 255.0, color[1] / 255.0, color[2] / 255.0, 0.5))
depth = np.array(fb.read_color(0, 0, width, height, 4, 0, 'FLOAT').to_list())
gpu.state.depth_test_set('NONE')
offscreen.free()
result = depth
e.set()
if threading.current_thread() == threading.main_thread():
_execute()
return result
else:
bpy.app.timers.register(_execute, first_interval=0)
e.wait()
return result
def draw_circle_2d(center, radius, segments, color):
m = (1.0 / (segments - 1)) * (math.pi * 2)
coords = [
(
center[0] + math.cos(m * p) * radius,
center[1] + math.sin(m * p) * radius,
0
)
for p in range(segments)
]
shader = gpu.shader.from_builtin(UNIFORM_COLOR)
batch = batch_for_shader(shader, 'TRI_FAN', {"pos": coords})
shader.uniform_float("color", color)
batch.draw(shader)
def draw_ellipse_2d(start, end, thickness, segments, color):
length = math.sqrt((end[0] - start[0]) ** 2 + (end[1] - start[1]) ** 2)
theta = math.atan2(end[1] - start[1], end[0] - start[0])
center = (
(start[0] + end[0]) / 2,
(start[1] + end[1]) / 2
)
major, minor = length / 2, thickness
m = (1.0 / (segments - 1)) * (math.pi * 2)
coords = [
(
center[0] + major * math.cos(m * p) * math.cos(theta) - minor * math.sin(m * p) * math.sin(theta),
center[1] + major * math.cos(m * p) * math.sin(theta) + minor * math.sin(m * p) * math.cos(theta),
0
)
for p in range(segments)
]
shader = gpu.shader.from_builtin(UNIFORM_COLOR)
batch = batch_for_shader(shader, 'TRI_FAN', {"pos": coords})
shader.uniform_float("color", color)
batch.draw(shader)
================================================
FILE: engine/annotations/viewport.py
================================================
import bpy
import gpu
import numpy as np
import threading
def render_viewport_color(context, width=None, height=None, matrix=None, projection_matrix=None, main_thread=False):
e = threading.Event()
result = None
width, height = width or context.scene.render.resolution_x, height or context.scene.render.resolution_y
matrix = matrix or context.scene.camera.matrix_world.inverted()
projection_matrix = projection_matrix or context.scene.camera.calc_matrix_camera(
context,
x=width,
y=height
)
def _execute():
nonlocal result
offscreen = gpu.types.GPUOffScreen(width, height)
with offscreen.bind():
fb = gpu.state.active_framebuffer_get()
fb.clear(color=(0.0, 0.0, 0.0, 0.0), depth=1)
gpu.state.depth_test_set('LESS_EQUAL')
gpu.state.depth_mask_set(True)
with gpu.matrix.push_pop():
gpu.matrix.load_matrix(matrix)
gpu.matrix.load_projection_matrix(projection_matrix)
area = next(a for a in bpy.context.screen.areas if a.type == 'VIEW_3D')
offscreen.draw_view3d(
context.scene,
context.view_layer,
next(s for s in area.spaces),
next(r for r in area.regions if r.type == 'WINDOW'),
matrix,
projection_matrix,
do_color_management=False
)
color = np.array(fb.read_color(0, 0, width, height, 4, 0, 'FLOAT').to_list())
gpu.state.depth_test_set('NONE')
offscreen.free()
result = color
e.set()
if main_thread or threading.current_thread() == threading.main_thread():
_execute()
return result
else:
bpy.app.timers.register(_execute, first_interval=0)
e.wait()
return result
================================================
FILE: engine/engine.py
================================================
import bpy
import gpu
from bl_ui.properties_render import RenderButtonsPanel
from bl_ui.properties_output import RenderOutputButtonsPanel
from bl_ui.properties_view_layer import ViewLayerButtonsPanel
import numpy as np
from ..ui.panels.dream_texture import optimization_panels
from .node_tree import DreamTexturesNodeTree
from ..engine import node_executor
from .annotations import depth
from ..property_groups.dream_prompt import backend_options
from .nodes.pipeline_nodes import NodeStableDiffusion
from .nodes.input_nodes import NodeRenderProperties
from ..generator_process import actor
from .. import image_utils
class DreamTexturesRenderEngine(bpy.types.RenderEngine):
"""A custom Dream Textures render engine, that uses Stable Diffusion and scene data to render images, instead of as a pass on top of Cycles."""
bl_idname = "DREAM_TEXTURES"
bl_label = "Dream Textures"
bl_use_preview = False
bl_use_postprocess = True
bl_use_gpu_context = actor.main_thread_rendering
def __init__(self):
pass
def __del__(self):
pass
def render(self, depsgraph):
scene = depsgraph.scene
result = self.begin_result(0, 0, scene.render.resolution_x, scene.render.resolution_y)
layer = result.layers[0].passes["Combined"]
self.update_result(result)
try:
progress = 0
def node_begin(node):
self.update_stats("Node", node.label or node.name)
def node_update(response):
if isinstance(response, np.ndarray):
try:
image_utils.np_to_render_pass(response, layer, top_to_bottom=False)
self.update_result(result)
except:
pass
def node_end(_):
nonlocal progress
progress += 1
self.update_progress(progress / len(scene.dream_textures_render_engine.node_tree.nodes))
group_outputs = node_executor.execute(scene.dream_textures_render_engine.node_tree, depsgraph, node_begin=node_begin, node_update=node_update, node_end=node_end, test_break=self.test_break)
node_result = group_outputs[0][1]
for k, v in group_outputs:
if type(v) == int or type(v) == str or type(v) == float:
self.get_result().stamp_data_add_field(k, str(v))
except Exception as error:
self.report({'ERROR'}, str(error))
raise error
image_utils.np_to_render_pass(node_result, layer, top_to_bottom=False)
if "Depth" in result.layers[0].passes:
z = depth.render_depth_map(depsgraph, invert=True)
image_utils.np_to_render_pass(z, result.layers[0].passes["Depth"], top_to_bottom=False)
self.end_result(result)
def update_render_passes(self, scene=None, renderlayer=None):
self.register_pass(scene, renderlayer, "Combined", 4, "RGBA", 'COLOR')
self.register_pass(scene, renderlayer, "Depth", 1, "Z", 'VALUE')
class NewEngineNodeTree(bpy.types.Operator):
bl_idname = "dream_textures.new_engine_node_tree"
bl_label = "New Node Tree"
def execute(self, context):
# TODO: Get the name of the default node tree from a config file
# TODO: type is deprecated https://docs.blender.org/api/current/bpy.types.NodeTree.html
# When testing the type of the resulting node tree using bpy.data.node_groups['Dream Textures Node Tree'].type it is '' because of that
bpy.ops.node.new_node_tree(type=DreamTexturesNodeTree.bl_idname, name="Dream Textures Node Editor")
# Get the newly generated node tree
node_tree = bpy.data.node_groups[-1]
node_sd = node_tree.nodes.new(type=NodeStableDiffusion.bl_idname)
node_sd.location = (200, 200)
node_out = node_tree.nodes.new(type="NodeGroupOutput")
# Blender 4.0 uses a new API for in- and outputs
if bpy.app.version[0] > 3:
node_tree.interface.new_socket('Image', description="Output of the final image.", in_out='OUTPUT', socket_type='NodeSocketColor')
else:
node_tree.outputs.new('NodeSocketColor','Image')
node_out.location = (400, 200)
node_tree.links.new(node_sd.outputs['Image'], node_out.inputs['Image'])
node_props = node_tree.nodes.new(type=NodeRenderProperties.bl_idname)
node_props.location = (0,200)
node_tree.links.new(node_props.outputs['Resolution X'], node_sd.inputs['Width'])
node_tree.links.new(node_props.outputs['Resolution Y'], node_sd.inputs['Height'])
# in case the node editor is open, synchronize the open node trees:
for area in context.screen.areas:
if area.type == 'NODE_EDITOR':
if area.spaces.active.tree_type == DreamTexturesNodeTree.bl_idname:
area.spaces.active.node_tree = node_tree
return {'FINISHED'}
def draw_device(self, context):
scene = context.scene
layout = self.layout
layout.use_property_split = True
layout.use_property_decorate = False
if context.engine == DreamTexturesRenderEngine.bl_idname:
layout.template_ID(scene.dream_textures_render_engine, "node_tree", text="Node Tree", new=NewEngineNodeTree.bl_idname)
layout.prop(scene.dream_textures_render_engine, "backend")
def _poll_node_tree(self, value):
return value.bl_idname == "DreamTexturesNodeTree"
def _update_engine_backend(self, context):
if self.node_tree is not None:
for node in self.node_tree.nodes:
if node.bl_idname == NodeStableDiffusion.bl_idname:
node.prompt.backend = self.backend
context.scene.dream_textures_engine_prompt.backend = self.backend
class DreamTexturesRenderEngineProperties(bpy.types.PropertyGroup):
node_tree: bpy.props.PointerProperty(type=DreamTexturesNodeTree, name="Node Tree", poll=_poll_node_tree)
backend: bpy.props.EnumProperty(name="Backend", items=backend_options, default=0, description="The backend to use for all pipeline nodes", update=_update_engine_backend)
def engine_panels():
bpy.types.RENDER_PT_output.COMPAT_ENGINES.add(DreamTexturesRenderEngine.bl_idname)
bpy.types.RENDER_PT_color_management.COMPAT_ENGINES.add(DreamTexturesRenderEngine.bl_idname)
bpy.types.RENDER_PT_stamp.COMPAT_ENGINES.add(DreamTexturesRenderEngine.bl_idname)
bpy.types.RENDER_PT_format.COMPAT_ENGINES.add(DreamTexturesRenderEngine.bl_idname)
bpy.types.DATA_PT_lens.COMPAT_ENGINES.add(DreamTexturesRenderEngine.bl_idname)
def get_prompt(context):
return context.scene.dream_textures_engine_prompt
class RenderPanel(bpy.types.Panel, RenderButtonsPanel):
COMPAT_ENGINES = {DreamTexturesRenderEngine.bl_idname}
def draw(self, context):
self.layout.use_property_decorate = True
class OutputPanel(bpy.types.Panel, RenderOutputButtonsPanel):
COMPAT_ENGINES = {DreamTexturesRenderEngine.bl_idname}
def draw(self, context):
self.layout.use_property_decorate = True
class ViewLayerPanel(bpy.types.Panel, ViewLayerButtonsPanel):
COMPAT_ENGINES = {DreamTexturesRenderEngine.bl_idname}
def draw(self, context):
pass
# Render Properties
yield from optimization_panels(RenderPanel, 'engine', get_prompt, "")
class NodeTreeInputsPanel(RenderPanel):
"""Create a subpanel for format options"""
bl_idname = f"DREAM_PT_dream_panel_node_tree_inputs_engine"
bl_label = "Inputs"
def draw(self, context):
super().draw(context)
layout = self.layout
layout.use_property_split = True
node_tree = context.scene.dream_textures_render_engine.node_tree
if node_tree is not None and hasattr(node_tree, "inputs"):
for input in node_tree.inputs:
layout.prop(input, "default_value", text=input.name)
yield NodeTreeInputsPanel
# View Layer
class ViewLayerPassesPanel(ViewLayerPanel):
bl_idname = "DREAM_PT_dream_panel_view_layer_passes"
bl_label = "Passes"
def draw(self, context):
layout = self.layout
layout.use_property_split = True
layout.use_property_decorate = False
view_layer = context.view_layer
col = layout.column()
col.prop(view_layer, "use_pass_combined")
col.prop(view_layer, "use_pass_z")
col.prop(view_layer, "use_pass_normal")
yield ViewLayerPassesPanel
# Bone properties
class OpenPoseArmaturePanel(bpy.types.Panel):
bl_idname = "DREAM_PT_dream_textures_armature_openpose"
bl_label = "OpenPose"
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "data"
@classmethod
def poll(cls, context):
return context.armature
def draw_header(self, context):
bone = context.bone or context.edit_bone
if bone:
self.layout.prop(bone.dream_textures_openpose, "enabled", text="")
def draw(self, context):
layout = self.layout
armature = context.armature
p = armature.dream_textures_openpose
row = layout.row()
row.prop(p, "EAR_L", toggle=True)
row.prop(p, "EYE_L", toggle=True)
row.prop(p, "EYE_R", toggle=True)
row.prop(p, "EAR_R", toggle=True)
layout.prop(p, "NOSE", toggle=True)
row = layout.row()
row.prop(p, "SHOULDER_L", toggle=True)
row.prop(p, "CHEST", toggle=True)
row.prop(p, "SHOULDER_R", toggle=True)
row = layout.row()
row.prop(p, "ELBOW_L", toggle=True)
row.separator()
row.prop(p, "HIP_L", toggle=True)
row.prop(p, "HIP_R", toggle=True)
row.separator()
row.prop(p, "ELBOW_R", toggle=True)
row = layout.row()
row.prop(p, "HAND_L", toggle=True)
row.separator()
row.prop(p, "KNEE_L", toggle=True)
row.prop(p, "KNEE_R", toggle=True)
row.separator()
row.prop(p, "HAND_R", toggle=True)
row = layout.row()
row.prop(p, "FOOT_L", toggle=True)
row.prop(p, "FOOT_R", toggle=True)
yield OpenPoseArmaturePanel
class OpenPoseBonePanel(bpy.types.Panel):
bl_idname = "DREAM_PT_dream_textures_bone_openpose"
bl_label = "OpenPose"
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "bone"
@classmethod
def poll(cls, context):
return context.bone and context.scene.render.engine == 'DREAM_TEXTURES'
def draw_header(self, context):
bone = context.bone
if bone:
self.layout.prop(bone.dream_textures_openpose, "enabled", text="")
def draw(self, context):
layout = self.layout
layout.use_property_split = True
bone = context.bone
layout.enabled = bone.dream_textures_openpose.enabled
layout.prop(bone.dream_textures_openpose, "bone")
layout.prop(bone.dream_textures_openpose, "side")
yield OpenPoseBonePanel
class ADE20KObjectPanel(bpy.types.Panel):
bl_idname = "DREAM_PT_dream_textures_object_ade20k"
bl_label = "ADE20K Segmentation"
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "object"
@classmethod
def poll(cls, context):
return context.object and context.scene.render.engine == 'DREAM_TEXTURES'
def draw_header(self, context):
object = context.object
if object:
self.layout.prop(object.dream_textures_ade20k, "enabled", text="")
def draw(self, context):
layout = self.layout
layout.use_property_split = True
object = context.object
layout.enabled = object.dream_textures_ade20k.enabled
r = layout.split(factor=0.9)
r.prop(object.dream_textures_ade20k, "annotation")
c = r.column()
c.enabled = False
c.prop(object.dream_textures_ade20k, "color")
yield ADE20KObjectPanel
================================================
FILE: engine/node.py
================================================
import bpy
from .node_tree import DreamTexturesNodeTree
class DreamTexturesNode(bpy.types.Node):
@classmethod
def poll(cls, tree):
return tree.bl_idname == DreamTexturesNodeTree.bl_idname
================================================
FILE: engine/node_executor.py
================================================
import bpy
# from dream_textures.engine import node_executor
# node_executor.execute(bpy.data.node_groups["NodeTree"], bpy.context.evaluated_depsgraph_get())
class NodeExecutionContext:
def __init__(self, depsgraph, start, update, end, test_break, cache={}):
self.depsgraph = depsgraph
self.start = start
self.update = update
self.end = end
self.test_break = test_break
self.cache = {}
self.preferences = bpy.context.preferences
def _evaluate_input(self, input):
if input.is_linked:
if len(input.links) > 1:
return [
self.execute(link.from_socket.node)[link.from_socket.name]
for link in input.links
]
else:
return self.execute(input.links[0].from_socket.node)[input.links[0].from_socket.name]
else:
return getattr(input, 'default_value', None)
def execute(self, node):
if self.test_break():
return None
result = None
match node.bl_idname:
case 'dream_textures.node_switch':
kwargs = {
'switch': self._evaluate_input(node.inputs[0]),
'false': lambda: self._evaluate_input(node.inputs[1]),
'true': lambda: self._evaluate_input(node.inputs[2])
}
self.start(node)
result = node.execute(self, **kwargs)
case _:
match node.type:
case 'GROUP_INPUT':
self.start(node)
result = {
input.name: input.default_value
for input in self.depsgraph.scene.dream_textures_render_engine.node_tree.inputs
}
case 'GROUP_OUTPUT':
self.start(node)
result = [
(input.name, self.execute(input.links[0].from_socket.node)[input.links[0].from_socket.name])
for input in node.inputs if len(input.links) > 0
]
case 'FRAME':
self.start(node)
result = None
case _:
if node in self.cache:
self.start(node)
result = self.cache[node]
else:
kwargs = {
input.name.lower().replace(' ', '_'): self._evaluate_input(input)
for input in node.inputs
}
self.start(node)
result = node.execute(self, **kwargs)
self.end(node)
return result
def execute(node_tree, depsgraph, node_begin=lambda node: None, node_update=lambda result: None, node_end=lambda node: None, test_break=lambda: False):
output = next(n for n in node_tree.nodes if n.type == 'GROUP_OUTPUT')
context = NodeExecutionContext(depsgraph, node_begin, node_update, node_end, test_break)
return context.execute(output)
================================================
FILE: engine/node_tree.py
================================================
import bpy
class DreamTexturesNodeTree(bpy.types.NodeTree):
bl_idname = "DreamTexturesNodeTree"
bl_label = "Dream Textures Node Editor"
bl_description = "Nodes for the Dream Textures Render Engine"
bl_icon = 'NODETREE'
@classmethod
def poll(cls, context):
return context.scene.render.engine == 'DREAM_TEXTURES'
================================================
FILE: engine/nodes/annotation_nodes.py
================================================
import bpy
from ..node import DreamTexturesNode
from ..annotations import depth
from ..annotations import normal
from ..annotations import openpose
from ..annotations import ade20k
from ..annotations import viewport
import numpy as np
annotation_src = (
('collection', 'Collection', 'Render the annotation for a specific collection'),
('scene', 'Scene', 'Render the annotation for the entire scene'),
)
def _update_annotation_inputs(self, context):
inputs = {socket.name: socket for socket in self.inputs}
inputs['Collection'].enabled = self.src == 'collection'
class NodeAnnotationDepth(DreamTexturesNode):
bl_idname = "dream_textures.node_annotation_depth"
bl_label = "Depth Map"
src: bpy.props.EnumProperty(name="", items=annotation_src, update=_update_annotation_inputs)
def init(self, context):
self.inputs.new("NodeSocketCollection", "Collection")
self.inputs.new("NodeSocketBool", "Invert")
self.outputs.new("NodeSocketColor", "Depth Map")
def draw_buttons(self, context, layout):
layout.prop(self, "src")
def execute(self, context, collection, invert):
depth_map = depth.render_depth_map(context.depsgraph, collection=collection if self.src == 'collection' else None, invert=invert)
context.update(depth_map)
return {
'Depth Map': depth_map,
}
class NodeAnnotationNormal(DreamTexturesNode):
bl_idname = "dream_textures.node_annotation_normal"
bl_label = "Normal Map"
src: bpy.props.EnumProperty(name="", items=annotation_src, update=_update_annotation_inputs)
def init(self, context):
self.inputs.new("NodeSocketCollection", "Collection")
self.outputs.new("NodeSocketColor", "Normal Map")
def draw_buttons(self, context, layout):
layout.prop(self, "src")
def execute(self, context, collection):
normal_map = normal.render_normal_map(context.depsgraph, collection=collection if self.src == 'collection' else None)
context.update(normal_map)
return {
'Normal Map': normal_map,
}
class NodeAnnotationOpenPose(DreamTexturesNode):
bl_idname = "dream_textures.node_annotation_openpose"
bl_label = "OpenPose Map"
src: bpy.props.EnumProperty(name="", items=annotation_src, update=_update_annotation_inputs)
def init(self, context):
self.inputs.new("NodeSocketCollection", "Collection")
self.outputs.new("NodeSocketColor", "OpenPose Map")
def draw_buttons(self, context, layout):
layout.prop(self, "src")
def execute(self, context, collection):
openpose_map = openpose.render_openpose_map(context.depsgraph, collection=collection if self.src == 'collection' else None)
context.update(openpose_map)
return {
'OpenPose Map': openpose_map
}
class NodeAnnotationADE20K(DreamTexturesNode):
bl_idname = "dream_textures.node_annotation_ade20k"
bl_label = "ADE20K Segmentation Map"
src: bpy.props.EnumProperty(name="", items=annotation_src, update=_update_annotation_inputs)
def init(self, context):
self.inputs.new("NodeSocketCollection", "Collection")
self.outputs.new("NodeSocketColor", "Segmentation Map")
def draw_buttons(self, context, layout):
layout.prop(self, "src")
def execute(self, context, collection):
ade20k_map = ade20k.render_ade20k_map(context.depsgraph, collection=collection if self.src == 'collection' else None)
context.update(ade20k_map)
return {
'Segmentation Map': ade20k_map
}
class NodeAnnotationViewport(DreamTexturesNode):
bl_idname = "dream_textures.node_annotation_viewport"
bl_label = "Viewport Color"
def init(self, context):
self.outputs.new("NodeSocketColor", "Viewport Color")
def draw_buttons(self, context, layout):
pass
def execute(self, context):
color = viewport.render_viewport_color(context.depsgraph)
context.update(color)
return {
'Viewport Color': color
}
================================================
FILE: engine/nodes/input_nodes.py
================================================
import bpy
import gpu
from gpu_extras.batch import batch_for_shader
import numpy as np
from ..node import DreamTexturesNode
from ..annotations import openpose
from ..annotations import depth
from ... import image_utils
class NodeString(DreamTexturesNode):
bl_idname = "dream_textures.node_string"
bl_label = "String"
value: bpy.props.StringProperty(name="")
def init(self, context):
self.outputs.new("NodeSocketString", "String")
def draw_buttons(self, context, layout):
layout.prop(self, "value")
def execute(self, context):
return {
'String': self.value
}
class NodeInteger(DreamTexturesNode):
bl_idname = "dream_textures.node_integer"
bl_label = "Integer"
value: bpy.props.IntProperty(name="")
def init(self, context):
self.outputs.new("NodeSocketInt", "Integer")
def draw_buttons(self, context, layout):
layout.prop(self, "value")
def execute(self, context):
return {
'Integer
gitextract_7tv49soa/ ├── .github/ │ ├── FUNDING.yml │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.yml │ │ └── feature_request.md │ └── workflows/ │ ├── package-release.yml │ └── stale.yml ├── .gitignore ├── .python_dependencies/ │ └── .gitignore ├── LICENSE ├── README.md ├── __init__.py ├── absolute_path.py ├── api/ │ ├── __init__.py │ ├── backend/ │ │ ├── __init__.py │ │ └── backend.py │ └── models/ │ ├── __init__.py │ ├── control_net.py │ ├── fix_it_error.py │ ├── generation_arguments.py │ ├── generation_result.py │ ├── model.py │ ├── prompt.py │ ├── seamless_axes.py │ ├── step_preview_mode.py │ └── task.py ├── builtin_presets/ │ ├── Debug.py │ ├── Final.py │ └── Preview.py ├── classes.py ├── community_backends/ │ └── test.py ├── diffusers_backend.py ├── docs/ │ ├── AI_UPSCALING.md │ ├── DEVELOPMENT_ENVIRONMENT.md │ ├── HISTORY.md │ ├── IMAGE_GENERATION.md │ ├── INPAINT_OUTPAINT.md │ ├── RENDER_PASS.md │ ├── SETUP.md │ ├── TEXTURE_PROJECTION.md │ └── assets/ │ └── banner_image_prompt.json ├── engine/ │ ├── __init__.py │ ├── annotations/ │ │ ├── ade20k.py │ │ ├── compat.py │ │ ├── depth.py │ │ ├── normal.py │ │ ├── openpose.py │ │ └── viewport.py │ ├── engine.py │ ├── node.py │ ├── node_executor.py │ ├── node_tree.py │ └── nodes/ │ ├── annotation_nodes.py │ ├── input_nodes.py │ ├── pipeline_nodes.py │ └── utility_nodes.py ├── generator_process/ │ ├── __init__.py │ ├── actions/ │ │ ├── choose_device.py │ │ ├── control_net.py │ │ ├── controlnet_aux.py │ │ ├── convert_original_stable_diffusion_to_diffusers.py │ │ ├── depth_to_image.py │ │ ├── detect_seamless/ │ │ │ ├── __init__.py │ │ │ └── model.npz │ │ ├── huggingface_hub.py │ │ ├── image_to_image.py │ │ ├── inpaint.py │ │ ├── load_model.py │ │ ├── outpaint.py │ │ ├── prompt_to_image.py │ │ └── upscale.py │ ├── actor.py │ ├── block_in_use.py │ ├── directml_patches.py │ ├── future.py │ └── models/ │ ├── __init__.py │ ├── checkpoint.py │ ├── image_generation_result.py │ ├── model_config.py │ ├── model_type.py │ ├── optimizations.py │ ├── scheduler.py │ └── upscale_tiler.py ├── image_utils.py ├── operators/ │ ├── dream_texture.py │ ├── inpaint_area_brush.py │ ├── install_dependencies.py │ ├── notify_result.py │ ├── open_latest_version.py │ ├── project.py │ ├── upscale.py │ └── view_history.py ├── preferences.py ├── prompt_engineering.py ├── property_groups/ │ ├── control_net.py │ ├── dream_prompt.py │ └── seamless_result.py ├── realtime_viewport.py ├── render_pass.py ├── requirements/ │ ├── linux-rocm.txt │ ├── mac-mps-cpu.txt │ ├── win-dml.txt │ └── win-linux-cuda.txt ├── scripts/ │ ├── train_detect_seamless.py │ └── zip_dependencies.py ├── sd_configs/ │ ├── cldm_v15.yaml │ ├── cldm_v21.yaml │ ├── sd_xl_base.yaml │ ├── sd_xl_refiner.yaml │ ├── v1-inference.yaml │ ├── v2-inference-v.yaml │ ├── v2-inference.yaml │ ├── v2-inpainting-inference.yaml │ └── v2-midas-inference.yaml ├── tools.py ├── ui/ │ ├── panels/ │ │ ├── dream_texture.py │ │ ├── history.py │ │ ├── render_properties.py │ │ └── upscaling.py │ ├── presets.py │ └── space_types.py └── version.py
SYMBOL INDEX (573 symbols across 77 files)
FILE: __init__.py
function clear_modules (line 33) | def clear_modules():
function register (line 62) | def register():
function unregister (line 136) | def unregister():
FILE: absolute_path.py
function absolute_path (line 3) | def absolute_path(component: str):
FILE: api/backend/backend.py
class Backend (line 11) | class Backend(bpy.types.PropertyGroup):
method register (line 29) | def register(cls):
method unregister (line 34) | def unregister(cls):
method _id (line 39) | def _id(cls) -> str:
method _attribute (line 43) | def _attribute(cls) -> str:
method _lookup (line 47) | def _lookup(cls, id):
method _list_backends (line 54) | def _list_backends(cls):
method list_models (line 57) | def list_models(self, context) -> List[Model]:
method list_controlnet_models (line 64) | def list_controlnet_models(self, context) -> List[Model]:
method list_schedulers (line 71) | def list_schedulers(self, context) -> List[str]:
method draw_prompt (line 75) | def draw_prompt(self, layout, context):
method draw_advanced (line 79) | def draw_advanced(self, layout, context):
method draw_speed_optimizations (line 83) | def draw_speed_optimizations(self, layout, context):
method draw_memory_optimizations (line 87) | def draw_memory_optimizations(self, layout, context):
method draw_extra (line 91) | def draw_extra(self, layout, context):
method get_batch_size (line 95) | def get_batch_size(self, context) -> int:
method generate (line 102) | def generate(
method validate (line 116) | def validate(
FILE: api/models/control_net.py
class ControlNet (line 6) | class ControlNet:
FILE: api/models/fix_it_error.py
class FixItError (line 5) | class FixItError(Exception):
method __init__ (line 10) | def __init__(self, message, solution: 'Solution'):
method _draw (line 15) | def _draw(self, dream_prompt, context, layout):
class Solution (line 19) | class Solution:
method _draw (line 20) | def _draw(self, dream_prompt, context, layout):
class ChangeProperty (line 24) | class ChangeProperty(Solution):
method _draw (line 28) | def _draw(self, dream_prompt, context, layout):
class RunOperator (line 32) | class RunOperator(Solution):
method _draw (line 38) | def _draw(self, dream_prompt, context, layout):
FILE: api/models/generation_arguments.py
class GenerationArguments (line 11) | class GenerationArguments:
method _map_property_name (line 79) | def _map_property_name(name: str) -> str | List[str] | None:
FILE: api/models/generation_result.py
class GenerationResult (line 7) | class GenerationResult:
method tile_images (line 51) | def tile_images(results: list['GenerationResult']) -> NDArray:
FILE: api/models/model.py
class Model (line 4) | class Model:
FILE: api/models/prompt.py
class Prompt (line 5) | class Prompt:
FILE: api/models/seamless_axes.py
class SeamlessAxes (line 3) | class SeamlessAxes(Enum):
method __init__ (line 19) | def __init__(self, id, text, x, y):
method __eq__ (line 25) | def __eq__(self, other):
method __and__ (line 40) | def __and__(self, other):
method __or__ (line 43) | def __or__(self, other):
method __xor__ (line 46) | def __xor__(self, other):
method __invert__ (line 49) | def __invert__(self):
method _missing_ (line 53) | def _missing_(cls, value):
method bpy_enum (line 74) | def bpy_enum(self, *args):
FILE: api/models/step_preview_mode.py
class StepPreviewMode (line 3) | class StepPreviewMode(enum.Enum):
FILE: api/models/task.py
class Task (line 6) | class Task:
method name (line 36) | def name(cls) -> str:
class PromptToImage (line 41) | class PromptToImage(Task):
method name (line 43) | def name(cls):
class ImageToImage (line 47) | class ImageToImage(Task):
method name (line 53) | def name(cls):
class Inpaint (line 57) | class Inpaint(ImageToImage):
class MaskSource (line 58) | class MaskSource(IntEnum):
method name (line 67) | def name(cls):
class DepthToImage (line 71) | class DepthToImage(Task):
method name (line 77) | def name(cls):
class Outpaint (line 81) | class Outpaint(Task):
method name (line 86) | def name(cls):
class Upscale (line 90) | class Upscale(Task):
method name (line 96) | def name(cls):
FILE: community_backends/test.py
class TestBackend (line 11) | class TestBackend(Backend):
method list_models (line 17) | def list_models(self, context) -> List[Model]:
method list_schedulers (line 20) | def list_schedulers(self, context) -> List[str]:
method generate (line 23) | def generate(self, task: Task, model: Model, prompt: Prompt, size: Tup...
method draw_speed_optimizations (line 26) | def draw_speed_optimizations(self, layout, context):
function register (line 29) | def register():
function unregister (line 32) | def unregister():
FILE: diffusers_backend.py
function _convert_models (line 18) | def _convert_models(models):
class DiffusersBackend (line 24) | class DiffusersBackend(Backend):
method list_models (line 82) | def list_models(self, context):
method list_controlnet_models (line 106) | def list_controlnet_models(self, context):
method list_schedulers (line 117) | def list_schedulers(self, context) -> List[str]:
method get_batch_size (line 120) | def get_batch_size(self, context) -> int:
method optimizations (line 123) | def optimizations(self) -> Optimizations:
method generate (line 133) | def generate(self, arguments: GenerationArguments, step_callback: Step...
method validate (line 251) | def validate(self, arguments: GenerationArguments):
method draw_advanced (line 278) | def draw_advanced(self, layout, context):
method draw_speed_optimizations (line 284) | def draw_speed_optimizations(self, layout, context):
method draw_memory_optimizations (line 298) | def draw_memory_optimizations(self, layout, context):
FILE: engine/__init__.py
class DreamTexturesNodeCategory (line 15) | class DreamTexturesNodeCategory(nodeitems_utils.NodeCategory):
method poll (line 17) | def poll(cls, context):
function register (line 73) | def register():
function unregister (line 131) | def unregister():
FILE: engine/annotations/ade20k.py
function annotation_update (line 11) | def annotation_update(self, context):
class ObjectADE20KData (line 14) | class ObjectADE20KData(bpy.types.PropertyGroup):
function render_ade20k_map (line 27) | def render_ade20k_map(context, collection=None, invert=True):
function draw_annotation (line 96) | def draw_annotation(vertices, indices, color):
FILE: engine/annotations/depth.py
function render_depth_map (line 8) | def render_depth_map(context, collection=None, invert=True, width=None, ...
FILE: engine/annotations/normal.py
function render_normal_map (line 8) | def render_normal_map(context, collection=None, width=None, height=None,...
FILE: engine/annotations/openpose.py
class Side (line 12) | class Side(enum.IntEnum):
class Bone (line 16) | class Bone(enum.IntEnum):
method identify (line 40) | def identify(self, armature, pose):
method name_detection_options (line 53) | def name_detection_options(self):
method color (line 92) | def color(self):
class BoneOpenPoseData (line 115) | class BoneOpenPoseData(bpy.types.PropertyGroup):
function render_openpose_map (line 135) | def render_openpose_map(context, collection=None):
function draw_circle_2d (line 227) | def draw_circle_2d(center, radius, segments, color):
function draw_ellipse_2d (line 244) | def draw_ellipse_2d(start, end, thickness, segments, color):
FILE: engine/annotations/viewport.py
function render_viewport_color (line 6) | def render_viewport_color(context, width=None, height=None, matrix=None,...
FILE: engine/engine.py
class DreamTexturesRenderEngine (line 17) | class DreamTexturesRenderEngine(bpy.types.RenderEngine):
method __init__ (line 26) | def __init__(self):
method __del__ (line 29) | def __del__(self):
method render (line 32) | def render(self, depsgraph):
method update_render_passes (line 70) | def update_render_passes(self, scene=None, renderlayer=None):
class NewEngineNodeTree (line 74) | class NewEngineNodeTree(bpy.types.Operator):
method execute (line 78) | def execute(self, context):
function draw_device (line 106) | def draw_device(self, context):
function _poll_node_tree (line 116) | def _poll_node_tree(self, value):
function _update_engine_backend (line 119) | def _update_engine_backend(self, context):
class DreamTexturesRenderEngineProperties (line 126) | class DreamTexturesRenderEngineProperties(bpy.types.PropertyGroup):
function engine_panels (line 130) | def engine_panels():
FILE: engine/node.py
class DreamTexturesNode (line 4) | class DreamTexturesNode(bpy.types.Node):
method poll (line 6) | def poll(cls, tree):
FILE: engine/node_executor.py
class NodeExecutionContext (line 5) | class NodeExecutionContext:
method __init__ (line 6) | def __init__(self, depsgraph, start, update, end, test_break, cache={}):
method _evaluate_input (line 15) | def _evaluate_input(self, input):
method execute (line 27) | def execute(self, node):
function execute (line 71) | def execute(node_tree, depsgraph, node_begin=lambda node: None, node_upd...
FILE: engine/node_tree.py
class DreamTexturesNodeTree (line 3) | class DreamTexturesNodeTree(bpy.types.NodeTree):
method poll (line 10) | def poll(cls, context):
FILE: engine/nodes/annotation_nodes.py
function _update_annotation_inputs (line 15) | def _update_annotation_inputs(self, context):
class NodeAnnotationDepth (line 19) | class NodeAnnotationDepth(DreamTexturesNode):
method init (line 25) | def init(self, context):
method draw_buttons (line 31) | def draw_buttons(self, context, layout):
method execute (line 34) | def execute(self, context, collection, invert):
class NodeAnnotationNormal (line 41) | class NodeAnnotationNormal(DreamTexturesNode):
method init (line 47) | def init(self, context):
method draw_buttons (line 52) | def draw_buttons(self, context, layout):
method execute (line 55) | def execute(self, context, collection):
class NodeAnnotationOpenPose (line 62) | class NodeAnnotationOpenPose(DreamTexturesNode):
method init (line 68) | def init(self, context):
method draw_buttons (line 73) | def draw_buttons(self, context, layout):
method execute (line 76) | def execute(self, context, collection):
class NodeAnnotationADE20K (line 83) | class NodeAnnotationADE20K(DreamTexturesNode):
method init (line 89) | def init(self, context):
method draw_buttons (line 94) | def draw_buttons(self, context, layout):
method execute (line 97) | def execute(self, context, collection):
class NodeAnnotationViewport (line 104) | class NodeAnnotationViewport(DreamTexturesNode):
method init (line 108) | def init(self, context):
method draw_buttons (line 111) | def draw_buttons(self, context, layout):
method execute (line 114) | def execute(self, context):
FILE: engine/nodes/input_nodes.py
class NodeString (line 10) | class NodeString(DreamTexturesNode):
method init (line 16) | def init(self, context):
method draw_buttons (line 19) | def draw_buttons(self, context, layout):
method execute (line 22) | def execute(self, context):
class NodeInteger (line 27) | class NodeInteger(DreamTexturesNode):
method init (line 33) | def init(self, context):
method draw_buttons (line 36) | def draw_buttons(self, context, layout):
method execute (line 39) | def execute(self, context):
class NodeCollection (line 44) | class NodeCollection(DreamTexturesNode):
method init (line 50) | def init(self, context):
method draw_buttons (line 53) | def draw_buttons(self, context, layout):
method execute (line 56) | def execute(self, context):
class NodeImage (line 61) | class NodeImage(DreamTexturesNode):
method init (line 67) | def init(self, context):
method draw_buttons (line 70) | def draw_buttons(self, context, layout):
method execute (line 75) | def execute(self, context):
class NodeImageFile (line 82) | class NodeImageFile(DreamTexturesNode):
method init (line 86) | def init(self, context):
method draw_buttons (line 91) | def draw_buttons(self, context, layout):
method execute (line 94) | def execute(self, context, path):
class NodeRenderProperties (line 101) | class NodeRenderProperties(DreamTexturesNode):
method init (line 105) | def init(self, context):
method draw_buttons (line 111) | def draw_buttons(self, context, layout):
method execute (line 114) | def execute(self, context):
FILE: engine/nodes/pipeline_nodes.py
class NodeSocketControlNet (line 19) | class NodeSocketControlNet(bpy.types.NodeSocket):
method __init__ (line 23) | def __init__(self):
method draw (line 26) | def draw(self, context, layout, node, text):
method draw_color (line 29) | def draw_color(self, context, node):
class ControlType (line 32) | class ControlType(enum.IntEnum):
class ControlNet (line 39) | class ControlNet:
method control (line 46) | def control(self, context):
function _update_stable_diffusion_sockets (line 60) | def _update_stable_diffusion_sockets(self, context):
class NodeStableDiffusion (line 68) | class NodeStableDiffusion(DreamTexturesNode):
method update (line 80) | def update(self):
method init (line 83) | def init(self, context):
method draw_buttons (line 104) | def draw_buttons(self, context, layout):
method execute (line 111) | def execute(self, context, prompt, negative_prompt, width, height, ste...
function _update_control_net_sockets (line 183) | def _update_control_net_sockets(self, context):
class NodeControlNet (line 187) | class NodeControlNet(DreamTexturesNode):
method init (line 203) | def init(self, context):
method draw_buttons (line 212) | def draw_buttons(self, context, layout):
method execute (line 218) | def execute(self, context, collection, image, conditioning_scale):
FILE: engine/nodes/utility_nodes.py
class NodeMath (line 8) | class NodeMath(DreamTexturesNode):
method init (line 22) | def init(self, context):
method draw_buttons (line 28) | def draw_buttons(self, context, layout):
method perform (line 31) | def perform(self, a, b):
method execute (line 42) | def execute(self, context, a, b):
class NodeRandomValue (line 47) | class NodeRandomValue(DreamTexturesNode):
method init (line 55) | def init(self, context):
method draw_buttons (line 61) | def draw_buttons(self, context, layout):
method execute (line 64) | def execute(self, context, min, max):
class NodeRandomSeed (line 69) | class NodeRandomSeed(DreamTexturesNode):
method init (line 73) | def init(self, context):
method draw_buttons (line 76) | def draw_buttons(self, context, layout):
method execute (line 79) | def execute(self, context):
class NodeSeed (line 84) | class NodeSeed(DreamTexturesNode):
method init (line 90) | def init(self, context):
method draw_buttons (line 93) | def draw_buttons(self, context, layout):
method execute (line 96) | def execute(self, context):
class NodeClamp (line 101) | class NodeClamp(DreamTexturesNode):
method init (line 105) | def init(self, context):
method draw_buttons (line 112) | def draw_buttons(self, context, layout):
method execute (line 115) | def execute(self, context, value, min, max):
class NodeFramePath (line 120) | class NodeFramePath(DreamTexturesNode):
method init (line 124) | def init(self, context):
method draw_buttons (line 129) | def draw_buttons(self, context, layout):
method execute (line 132) | def execute(self, context, frame):
class NodeCropImage (line 137) | class NodeCropImage(DreamTexturesNode):
method init (line 141) | def init(self, context):
method draw_buttons (line 150) | def draw_buttons(self, context, layout):
method execute (line 153) | def execute(self, context, image, x, y, width, height):
class NodeResizeImage (line 162) | class NodeResizeImage(DreamTexturesNode):
method init (line 166) | def init(self, context):
method draw_buttons (line 173) | def draw_buttons(self, context, layout):
method execute (line 176) | def execute(self, context, image, width, height):
class NodeJoinImages (line 183) | class NodeJoinImages(DreamTexturesNode):
method init (line 192) | def init(self, context):
method draw_buttons (line 198) | def draw_buttons(self, context, layout):
method execute (line 201) | def execute(self, context, a, b):
class NodeSeparateColor (line 212) | class NodeSeparateColor(DreamTexturesNode):
method init (line 216) | def init(self, context):
method draw_buttons (line 224) | def draw_buttons(self, context, layout):
method execute (line 227) | def execute(self, context, color):
class NodeCombineColor (line 235) | class NodeCombineColor(DreamTexturesNode):
method init (line 239) | def init(self, context):
method draw_buttons (line 247) | def draw_buttons(self, context, layout):
method execute (line 250) | def execute(self, context, red, green, blue, alpha):
class NodeColorCorrect (line 255) | class NodeColorCorrect(DreamTexturesNode):
method init (line 263) | def init(self, context):
method draw_buttons (line 269) | def draw_buttons(self, context, layout):
method execute (line 272) | def execute(self, context, image, target):
class NodeSwitch (line 292) | class NodeSwitch(DreamTexturesNode):
method init (line 296) | def init(self, context):
method draw_buttons (line 303) | def draw_buttons(self, context, layout):
method execute (line 306) | def execute(self, context, switch, false, true):
class NodeCompare (line 311) | class NodeCompare(DreamTexturesNode):
method init (line 324) | def init(self, context):
method draw_buttons (line 330) | def draw_buttons(self, context, layout):
method execute (line 333) | def execute(self, context, a, b):
class NodeReplaceString (line 351) | class NodeReplaceString(DreamTexturesNode):
method init (line 355) | def init(self, context):
method draw_buttons (line 362) | def draw_buttons(self, context, layout):
method execute (line 365) | def execute(self, context, string, find, replace):
FILE: generator_process/__init__.py
class RunInSubprocess (line 5) | class RunInSubprocess(Exception):
method __new__ (line 12) | def __new__(cls, func=None):
method always (line 19) | def always(func):
method when (line 28) | def when(condition: bool | Callable[..., bool]):
method when_raised (line 45) | def when_raised(func):
method _copy_attributes (line 57) | def _copy_attributes(src, dst):
class Generator (line 62) | class Generator(Actor):
method call (line 82) | def call(func, *args, **kwargs):
FILE: generator_process/actions/choose_device.py
function choose_device (line 4) | def choose_device(self, optimizations) -> str:
FILE: generator_process/actions/control_net.py
function control_net (line 14) | def control_net(
FILE: generator_process/actions/controlnet_aux.py
function controlnet_aux (line 6) | def controlnet_aux(
FILE: generator_process/actions/convert_original_stable_diffusion_to_diffusers.py
function convert_original_stable_diffusion_to_diffusers (line 8) | def convert_original_stable_diffusion_to_diffusers(
FILE: generator_process/actions/depth_to_image.py
function depth_to_image (line 12) | def depth_to_image(
FILE: generator_process/actions/detect_seamless/__init__.py
function detect_seamless (line 9) | def detect_seamless(self, image: image_utils.ImageOrPath) -> SeamlessAxes:
FILE: generator_process/actions/huggingface_hub.py
class Model (line 22) | class Model:
function hf_list_models (line 30) | def hf_list_models(
function hf_list_installed_models (line 54) | def hf_list_installed_models(self) -> list[Model]:
class DownloadStatus (line 120) | class DownloadStatus:
method hook_download_tqdm (line 126) | def hook_download_tqdm(cls, future):
function hf_snapshot_download (line 156) | def hf_snapshot_download(
FILE: generator_process/actions/image_to_image.py
function image_to_image (line 14) | def image_to_image(
FILE: generator_process/actions/inpaint.py
function inpaint (line 11) | def inpaint(
FILE: generator_process/actions/load_model.py
function revision_paths (line 9) | def revision_paths(model, config="model_index.json"):
function cache_check (line 37) | def cache_check(*, exists_callback=None):
function _load_controlnet_model (line 52) | def _load_controlnet_model(cache, model, half_precision):
function _load_checkpoint (line 94) | def _load_checkpoint(model_class, checkpoint, dtype, **kwargs):
function _convert_pipe (line 136) | def _convert_pipe(cache, model, pipe, model_class, half_precision, sched...
function _load_pipeline (line 148) | def _load_pipeline(cache, model, model_class, half_precision, scheduler,...
function load_model (line 185) | def load_model(self, model_class, model, optimizations, scheduler, contr...
FILE: generator_process/actions/outpaint.py
function outpaint (line 7) | def outpaint(
FILE: generator_process/actions/prompt_to_image.py
function prompt_to_image (line 13) | def prompt_to_image(
function _conv_forward_asymmetric (line 128) | def _conv_forward_asymmetric(self, input, weight, bias):
function _lora_compatible_conv_forward (line 151) | def _lora_compatible_conv_forward(self, hidden_states, scale=1.0):
function _configure_model_padding (line 154) | def _configure_model_padding(model, seamless_axes):
FILE: generator_process/actions/upscale.py
function upscale (line 11) | def upscale(
FILE: generator_process/actor.py
function _patch_zip_direct_transformers_import (line 13) | def _patch_zip_direct_transformers_import():
function _load_dependencies (line 26) | def _load_dependencies():
function main_thread_rendering_finished (line 55) | def main_thread_rendering_finished():
class ActorContext (line 61) | class ActorContext(enum.IntEnum):
class Message (line 71) | class Message:
method __init__ (line 78) | def __init__(self, method_name, args, kwargs):
function _start_backend (line 86) | def _start_backend(cls, message_queue, response_queue):
class TracedError (line 93) | class TracedError(BaseException):
method __init__ (line 94) | def __init__(self, base: BaseException, trace: str):
class Actor (line 100) | class Actor:
method __init__ (line 125) | def __init__(self, context: ActorContext, message_queue: Queue = None,...
method _setup (line 132) | def _setup(self):
method shared (line 145) | def shared(cls: Type[T]) -> T:
method start (line 148) | def start(self: T) -> T:
method close (line 172) | def close(self):
method shared_close (line 185) | def shared_close(cls: Type[T]):
method is_alive (line 191) | def is_alive(self):
method can_use (line 198) | def can_use(self):
method _backend_loop (line 203) | def _backend_loop(self):
method _receive (line 207) | def _receive(self, message: Message):
method _send (line 245) | def _send(self, name):
method __del__ (line 277) | def __del__(self):
FILE: generator_process/block_in_use.py
function block_in_use (line 1) | def block_in_use(func):
FILE: generator_process/directml_patches.py
function pad (line 10) | def pad(input, pad, mode="constant", value=None, *, pre_patch):
function layer_norm (line 32) | def layer_norm(input, normalized_shape, weight = None, bias = None, eps ...
function retry_OOM (line 38) | def retry_OOM(module):
function enable (line 81) | def enable(pipe):
function disable (line 134) | def disable(pipe):
FILE: generator_process/future.py
class Future (line 5) | class Future:
method __init__ (line 22) | def __init__(self):
method result (line 33) | def result(self, last_only=False):
method exception (line 55) | def exception(self):
method cancel (line 62) | def cancel(self):
method _run_on_main_thread (line 65) | def _run_on_main_thread(self, func):
method add_response (line 75) | def add_response(self, response):
method set_exception (line 85) | def set_exception(self, exception: BaseException):
method set_done (line 95) | def set_done(self):
method add_response_callback (line 108) | def add_response_callback(self, callback: Callable[['Future', Any], No...
method add_exception_callback (line 115) | def add_exception_callback(self, callback: Callable[['Future', BaseExc...
method add_done_callback (line 124) | def add_done_callback(self, callback: Callable[['Future'], None]):
FILE: generator_process/models/checkpoint.py
class Checkpoint (line 7) | class Checkpoint:
FILE: generator_process/models/image_generation_result.py
function step_latents (line 4) | def step_latents(pipe, mode, latents, generator, iteration, steps):
function step_images (line 54) | def step_images(images, generator, iteration, steps):
function decode_latents (line 68) | def decode_latents(pipe, latents):
function approximate_decoded_latents (line 71) | def approximate_decoded_latents(latents, scale=None):
FILE: generator_process/models/model_config.py
class ModelConfig (line 6) | class ModelConfig(enum.Enum):
method original_config (line 19) | def original_config(self):
method pipeline (line 43) | def pipeline(self):
FILE: generator_process/models/model_type.py
class ModelType (line 7) | class ModelType(enum.IntEnum):
method _missing_ (line 21) | def _missing_(cls, _):
method recommended_model (line 24) | def recommended_model(self) -> str:
method matches_task (line 41) | def matches_task(self, task: Task) -> bool:
method from_task (line 63) | def from_task(task: Task) -> 'ModelType | None':
method from_config (line 79) | def from_config(config: ModelConfig):
FILE: generator_process/models/optimizations.py
class CPUOffload (line 11) | class CPUOffload(Enum):
method __bool__ (line 16) | def __bool__(self):
class Optimizations (line 21) | class Optimizations:
method infer_device (line 41) | def infer_device() -> str:
method device_supports (line 51) | def device_supports(cls, property, device) -> bool:
method can_use (line 60) | def can_use(self, property, device) -> bool:
method can_use_half (line 63) | def can_use_half(self, device):
method cpu_offloading (line 70) | def cpu_offloading(self, device):
method apply (line 73) | def apply(self, pipeline, device):
FILE: generator_process/models/scheduler.py
class Scheduler (line 3) | class Scheduler(enum.Enum):
method create (line 23) | def create(self, pipeline):
FILE: generator_process/models/upscale_tiler.py
class UpscaleTiler (line 9) | class UpscaleTiler:
method __init__ (line 10) | def __init__(
method axis_tiles (line 60) | def axis_tiles(axis_size: int, tile_size: int, blend: int, seamless: b...
method combined (line 76) | def combined(self) -> NDArray:
method index_to_xy (line 79) | def index_to_xy(self, index: int):
method __getitem__ (line 84) | def __getitem__(self, key: int | tuple[int, int]) -> NDArray:
method __setitem__ (line 120) | def __setitem__(self, key: int | tuple[int, int], tile: NDArray):
method __iter__ (line 157) | def __iter__(self):
method __len__ (line 162) | def __len__(self):
function tiled_decode_latents (line 166) | def tiled_decode_latents(self, latents, return_dict=False, *, pre_patch,...
function configure_model_padding (line 210) | def configure_model_padding(model, seamless_axes):
function _conv_forward_asymmetric (line 240) | def _conv_forward_asymmetric(self, input, weight, bias):
FILE: image_utils.py
function version_str (line 29) | def version_str(version):
function _bpy_version_error (line 57) | def _bpy_version_error(required_version, feature, module):
function size (line 63) | def size(array: NDArray) -> Tuple[int, int]:
function channels (line 71) | def channels(array: NDArray) -> int:
function ensure_alpha (line 79) | def ensure_alpha(array: NDArray, alpha=None) -> NDArray:
function ensure_opaque (line 103) | def ensure_opaque(array: NDArray) -> NDArray:
function ensure_channel_dim (line 112) | def ensure_channel_dim(array: NDArray) -> NDArray:
function rgb (line 121) | def rgb(array: NDArray) -> NDArray:
function rgba (line 139) | def rgba(array: NDArray, alpha=None) -> NDArray:
function grayscale (line 156) | def grayscale(array: NDArray) -> NDArray:
function _passthrough_alpha (line 180) | def _passthrough_alpha(from_array, to_array):
function linear_to_srgb (line 187) | def linear_to_srgb(array: NDArray, clamp=True) -> NDArray:
function srgb_to_linear (line 209) | def srgb_to_linear(array: NDArray) -> NDArray:
function color_transform (line 226) | def color_transform(array: NDArray, from_color_space: str, to_color_spac...
function render_color_transform (line 289) | def render_color_transform(
function scene_color_transform (line 396) | def scene_color_transform(array: NDArray, scene: Union["bpy.types.Scene"...
function _unsigned (line 415) | def _unsigned(dtype: DTypeLike) -> DTypeLike:
function to_dtype (line 428) | def to_dtype(array: NDArray, dtype: DTypeLike) -> NDArray:
function resize (line 501) | def resize(array: NDArray, size: Tuple[int, int], clamp=True):
function bpy_to_np (line 549) | def bpy_to_np(image: "bpy.types.Image", *, color_space: str | None = "sR...
function np_to_bpy (line 578) | def np_to_bpy(array: NDArray, name=None, existing_image=None, float_buff...
function render_pass_to_np (line 645) | def render_pass_to_np(
function np_to_render_pass (line 668) | def np_to_render_pass(
function _mode (line 701) | def _mode(array, mode):
function pil_to_np (line 715) | def pil_to_np(image, *, dtype: DTypeLike | None = np.float32, mode: Lite...
function np_to_pil (line 727) | def np_to_pil(array: NDArray, *, mode: Literal["RGB", "RGBA", "L", "LA"]...
function _dtype_to_type_desc (line 741) | def _dtype_to_type_desc(dtype):
function path_to_np (line 772) | def path_to_np(
function image_to_np (line 812) | def image_to_np(
FILE: operators/dream_texture.py
function get_source_image (line 16) | def get_source_image(context, source: Literal['file', 'open_editor']):
class DreamTexture (line 33) | class DreamTexture(bpy.types.Operator):
method poll (line 40) | def poll(cls, context):
method execute (line 49) | def execute(self, context):
function kill_generator (line 222) | def kill_generator(context=bpy.context):
class ReleaseGenerator (line 231) | class ReleaseGenerator(bpy.types.Operator):
method execute (line 237) | def execute(self, context):
class CancelGenerator (line 241) | class CancelGenerator(bpy.types.Operator):
method poll (line 250) | def poll(cls, context):
method execute (line 253) | def execute(self, context):
FILE: operators/inpaint_area_brush.py
class InpaintAreaBrushActivated (line 6) | class InpaintAreaBrushActivated(bpy.types.GizmoGroup):
method setup (line 13) | def setup(self, context):
method __del__ (line 27) | def __del__(self):
class InpaintAreaBrush (line 32) | class InpaintAreaBrush(bpy.types.WorkSpaceTool):
method draw_settings (line 42) | def draw_settings(self, layout, tool):
FILE: operators/install_dependencies.py
class PipInstall (line 14) | class PipInstall(IntEnum):
function install_pip (line 19) | def install_pip(method = PipInstall.STANDARD):
function install_pip_any (line 62) | def install_pip_any(*methods):
function get_pip_install (line 73) | def get_pip_install():
function install_and_import_requirements (line 97) | def install_and_import_requirements(requirements_txt=None, pip_install=P...
class InstallDependencies (line 133) | class InstallDependencies(bpy.types.Operator):
method invoke (line 139) | def invoke(self, context, event):
method execute (line 142) | def execute(self, context):
class UninstallDependencies (line 162) | class UninstallDependencies(bpy.types.Operator):
method execute (line 170) | def execute(self, context):
FILE: operators/notify_result.py
class NotifyResult (line 5) | class NotifyResult(bpy.types.Operator):
method modal (line 13) | def modal(self, context, event):
method invoke (line 22) | def invoke(self, context, event):
method execute (line 26) | def execute(self, context):
FILE: operators/open_latest_version.py
function check_for_updates (line 10) | def check_for_updates():
function new_version_available (line 19) | def new_version_available():
function do_force_show_download (line 23) | def do_force_show_download():
function is_force_show_download (line 26) | def is_force_show_download():
class OpenLatestVersion (line 29) | class OpenLatestVersion(bpy.types.Operator):
method poll (line 36) | def poll(cls, context):
method execute (line 39) | def execute(self, context):
FILE: operators/project.py
function _validate_projection (line 33) | def _validate_projection(context):
function dream_texture_projection_panels (line 72) | def dream_texture_projection_panels():
function bake (line 182) | def bake(context, mesh, src, dest, src_uv, dest_uv):
class ProjectDreamTexture (line 238) | class ProjectDreamTexture(bpy.types.Operator):
method poll (line 245) | def poll(cls, context):
method get_uv_layer (line 258) | def get_uv_layer(cls, mesh: bmesh.types.BMesh):
method execute (line 266) | def execute(self, context):
FILE: operators/upscale.py
function get_source_image (line 16) | def get_source_image(context):
class Upscale (line 31) | class Upscale(bpy.types.Operator):
method poll (line 38) | def poll(cls, context):
method execute (line 41) | def execute(self, context):
FILE: operators/view_history.py
class SCENE_UL_HistoryList (line 8) | class SCENE_UL_HistoryList(bpy.types.UIList):
method draw_item (line 9) | def draw_item(self, context, layout, data, item, icon, active_data, ac...
class RecallHistoryEntry (line 20) | class RecallHistoryEntry(bpy.types.Operator):
method poll (line 27) | def poll(self, context):
method execute (line 30) | def execute(self, context):
class ClearHistory (line 61) | class ClearHistory(bpy.types.Operator):
method execute (line 67) | def execute(self, context):
class RemoveHistorySelection (line 72) | class RemoveHistorySelection(bpy.types.Operator):
method poll (line 79) | def poll(self, context):
method execute (line 82) | def execute(self, context):
class ExportHistorySelection (line 87) | class ExportHistorySelection(bpy.types.Operator, ExportHelper):
method poll (line 101) | def poll(self, context):
method invoke (line 104) | def invoke(self, context, event):
method execute (line 110) | def execute(self, context):
class ImportPromptFile (line 122) | class ImportPromptFile(bpy.types.Operator, ImportHelper):
method execute (line 135) | def execute(self, context):
FILE: preferences.py
class OpenURL (line 19) | class OpenURL(bpy.types.Operator):
method execute (line 27) | def execute(self, context):
class ImportWeights (line 34) | class ImportWeights(bpy.types.Operator, ImportHelper):
method execute (line 52) | def execute(self, context):
class Model (line 71) | class Model(bpy.types.PropertyGroup):
class PREFERENCES_UL_ModelList (line 81) | class PREFERENCES_UL_ModelList(bpy.types.UIList):
method draw_item (line 82) | def draw_item(self, context, layout, data, item, icon, active_data, ac...
function set_model_list (line 101) | def set_model_list(model_list: str, models: list):
class checkpoint_lookup (line 114) | class checkpoint_lookup:
method get (line 118) | def get(cls, item):
class model_lookup (line 121) | class model_lookup:
method get (line 125) | def get(cls, item):
function fetch_installed_models (line 128) | def fetch_installed_models(blocking=True):
class ModelSearch (line 166) | class ModelSearch(bpy.types.Operator):
method execute (line 172) | def execute(self, context):
class InstallModel (line 176) | class InstallModel(bpy.types.Operator):
method execute (line 186) | def execute(self, context):
function _model_search (line 216) | def _model_search(self, context):
function _update_ui (line 221) | def _update_ui(self, context):
function _template_model_download_progress (line 228) | def _template_model_download_progress(context, layout):
class CheckpointGroup (line 238) | class CheckpointGroup(bpy.types.PropertyGroup):
class LinkCheckpoint (line 248) | class LinkCheckpoint(bpy.types.Operator, ImportHelper):
method invoke (line 266) | def invoke(self, context, _event):
method execute (line 272) | def execute(self, context):
class UnlinkCheckpoint (line 296) | class UnlinkCheckpoint(bpy.types.Operator):
method execute (line 301) | def execute(self, context):
class PREFERENCES_UL_CheckpointList (line 311) | class PREFERENCES_UL_CheckpointList(bpy.types.UIList):
method draw_item (line 312) | def draw_item(self, context, layout, data, item, icon, active_data, ac...
class StableDiffusionPreferences (line 321) | class StableDiffusionPreferences(bpy.types.AddonPreferences):
method register (line 345) | def register():
method draw (line 348) | def draw(self, context):
FILE: prompt_engineering.py
function texture_prompt (line 75) | def texture_prompt(tokens):
function photography_prompt (line 84) | def photography_prompt(tokens):
function concept_art_prompt (line 108) | def concept_art_prompt(tokens):
function custom_prompt (line 118) | def custom_prompt(tokens):
function file_batch_prompt (line 127) | def file_batch_prompt(tokens):
function map_structure (line 144) | def map_structure(x):
FILE: property_groups/control_net.py
function control_net_options (line 9) | def control_net_options(self, context):
class ControlNet (line 50) | class ControlNet(bpy.types.PropertyGroup):
class ControlNetsAddMenu (line 61) | class ControlNetsAddMenu(bpy.types.Menu):
method draw (line 65) | def draw(self, context):
class ControlNetsAdd (line 74) | class ControlNetsAdd(bpy.types.Operator):
method execute (line 80) | def execute(self, context):
class ControlNetsRemove (line 84) | class ControlNetsRemove(bpy.types.Operator):
method execute (line 90) | def execute(self, context):
class BakeControlNetImage (line 94) | class BakeControlNetImage(bpy.types.Operator):
method execute (line 101) | def execute(self, context):
FILE: property_groups/dream_prompt.py
function scheduler_options (line 20) | def scheduler_options(self, context):
function init_image_actions_filtered (line 46) | def init_image_actions_filtered(self, context):
function inpaint_mask_sources_filtered (line 55) | def inpaint_mask_sources_filtered(self, context):
function modify_action_source_type (line 67) | def modify_action_source_type(self, context):
function model_options (line 76) | def model_options(self, context):
function _model_update (line 82) | def _model_update(self, context):
function backend_options (line 87) | def backend_options(self, context):
function seed_clamp (line 93) | def seed_clamp(self, ctx):
function map_structure_token_items (line 154) | def map_structure_token_items(value):
function generate_prompt (line 172) | def generate_prompt(self):
function get_prompt_subject (line 188) | def get_prompt_subject(self):
function get_seed (line 195) | def get_seed(self):
function generate_args (line 208) | def generate_args(self, context, iteration=0, init_image=None, control_i...
function get_backend (line 291) | def get_backend(self) -> api.Backend:
FILE: property_groups/seamless_result.py
function update (line 10) | def update(self, context):
class SeamlessResult (line 17) | class SeamlessResult(bpy.types.PropertyGroup):
method check (line 24) | def check(self, image):
method update_args (line 54) | def update_args(self, args, as_id=False):
FILE: realtime_viewport.py
function debounce (line 15) | def debounce(wait_time):
function DREAMTEXTURES_HT_viewport_enabled (line 39) | def DREAMTEXTURES_HT_viewport_enabled(self, context):
function create_image (line 51) | def create_image():
function register_realtime_viewport (line 56) | def register_realtime_viewport():
function unregister_realtime_viewport (line 159) | def unregister_realtime_viewport():
FILE: render_pass.py
function register_render_pass (line 21) | def register_render_pass():
function unregister_render_pass (line 77) | def unregister_render_pass():
function _render_dream_textures_pass (line 86) | def _render_dream_textures_pass(self, layer, size, scene, render_pass, r...
FILE: scripts/train_detect_seamless.py
class SeamlessModel (line 43) | class SeamlessModel(nn.Module):
method __init__ (line 44) | def __init__(self):
method forward (line 62) | def forward(self, x: torch.Tensor):
function image_edges (line 76) | def image_edges(path):
function prepare_edge (line 92) | def prepare_edge(edge: NDArray, axis: str) -> torch.Tensor:
function prepare_edges (line 103) | def prepare_edges(edge_x: NDArray, edge_y: NDArray) -> tuple[torch.Tenso...
function seamless_tensor (line 111) | def seamless_tensor(seamless):
class EdgeDataset (line 115) | class EdgeDataset(Dataset):
method __init__ (line 116) | def __init__(self, path):
method _load_dir (line 124) | def _load_dir(self, imdir, seamless):
method __len__ (line 140) | def __len__(self):
method __getitem__ (line 143) | def __getitem__(self, idx) -> tuple[torch.Tensor, torch.Tensor, str, s...
class PermutedEdgeDataset (line 164) | class PermutedEdgeDataset(Dataset):
method __init__ (line 167) | def __init__(self, dataset: EdgeDataset | str):
method __len__ (line 172) | def __len__(self):
method __getitem__ (line 175) | def __getitem__(self, idx):
function mix_iter (line 185) | def mix_iter(*iterables):
function train (line 208) | def train(model: nn.Module, train_datasets, valid_datasets, epochs=1000,...
function validate (line 277) | def validate(model, datasets):
function save_npz (line 320) | def save_npz(path, state_dict):
function load_npz (line 324) | def load_npz(path):
function main (line 332) | def main():
FILE: scripts/zip_dependencies.py
function main (line 6) | def main():
FILE: ui/panels/dream_texture.py
function dream_texture_panels (line 15) | def dream_texture_panels():
function create_panel (line 71) | def create_panel(space_type, region_type, parent_id, ctor, get_prompt, u...
function prompt_panel (line 88) | def prompt_panel(sub_panel, space_type, get_prompt, get_seamless_result=...
function size_panel (line 149) | def size_panel(sub_panel, space_type, get_prompt):
function init_image_panels (line 169) | def init_image_panels(sub_panel, space_type, get_prompt):
function control_net_panel (line 226) | def control_net_panel(sub_panel, space_type, get_prompt):
function advanced_panel (line 259) | def advanced_panel(sub_panel, space_type, get_prompt):
function optimization_panels (line 291) | def optimization_panels(sub_panel, space_type, get_prompt, parent_id=""):
function actions_panel (line 324) | def actions_panel(sub_panel, space_type, get_prompt):
FILE: ui/panels/history.py
function history_panels (line 10) | def history_panels():
FILE: ui/panels/render_properties.py
class RenderPropertiesPanel (line 7) | class RenderPropertiesPanel(bpy.types.Panel):
method poll (line 17) | def poll(self, context):
method draw_header (line 20) | def draw_header(self, context):
method draw (line 23) | def draw(self, context):
function render_properties_panels (line 51) | def render_properties_panels():
FILE: ui/panels/upscaling.py
function upscaling_panels (line 9) | def upscaling_panels():
FILE: ui/presets.py
class DreamTexturesPresetPanel (line 11) | class DreamTexturesPresetPanel(PresetPanel, Panel):
class DREAM_PT_AdvancedPresets (line 14) | class DREAM_PT_AdvancedPresets(DreamTexturesPresetPanel):
class DREAM_MT_AdvancedPresets (line 19) | class DREAM_MT_AdvancedPresets(Menu):
class AddAdvancedPreset (line 25) | class AddAdvancedPreset(AddPresetBase, Operator):
class RestoreDefaultPresets (line 53) | class RestoreDefaultPresets(Operator):
method execute (line 59) | def execute(self, context):
function register_default_presets (line 65) | def register_default_presets(force=False):
function default_presets_missing (line 74) | def default_presets_missing():
FILE: version.py
function version_tag (line 2) | def version_tag(version):
function version_tuple (line 5) | def version_tuple(tag):
Condensed preview — 120 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (589K chars).
[
{
"path": ".github/FUNDING.yml",
"chars": 816,
"preview": "# These are supported funding model platforms\n\ngithub: carson-katri # Replace with up to 4 GitHub Sponsors-enabled usern"
},
{
"path": ".github/ISSUE_TEMPLATE/bug_report.yml",
"chars": 2278,
"preview": "name: Bug Report\ndescription: File a bug report\ntitle: \"<title>\"\nlabels: [\"bug\"]\nbody:\n - type: markdown\n attributes"
},
{
"path": ".github/ISSUE_TEMPLATE/feature_request.md",
"chars": 604,
"preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: enhancement\nassignees: ''\n\n---\n\n**Is"
},
{
"path": ".github/workflows/package-release.yml",
"chars": 1937,
"preview": "name: Package Release\non:\n push:\n branches:\n - \"releases/**\"\n workflow_dispatch:\n\njobs:\n package-release:\n "
},
{
"path": ".github/workflows/stale.yml",
"chars": 750,
"preview": "name: Close inactive issues\non:\n schedule:\n - cron: \"30 1 * * *\"\n workflow_dispatch:\n\njobs:\n close-issues:\n run"
},
{
"path": ".gitignore",
"chars": 3114,
"preview": ".DS_Store\n\n# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\n# C extensions\n*.so\n\n# Distributio"
},
{
"path": ".python_dependencies/.gitignore",
"chars": 13,
"preview": "*\n!.gitignore"
},
{
"path": "LICENSE",
"chars": 35149,
"preview": " GNU GENERAL PUBLIC LICENSE\n Version 3, 29 June 2007\n\n Copyright (C) 2007 Free "
},
{
"path": "README.md",
"chars": 5318,
"preview": "\n\n[:\n \"\"\"\n Returns the absolute path to a file in the addon directory.\n\n "
},
{
"path": "api/__init__.py",
"chars": 44,
"preview": "from .models import *\nfrom .backend import *"
},
{
"path": "api/backend/__init__.py",
"chars": 22,
"preview": "from .backend import *"
},
{
"path": "api/backend/backend.py",
"chars": 4651,
"preview": "try:\n import bpy\n from typing import Callable, List, Tuple\n from ..models.generation_arguments import Generatio"
},
{
"path": "api/models/__init__.py",
"chars": 185,
"preview": "from .generation_result import *\nfrom .model import *\nfrom .prompt import *\nfrom .seamless_axes import *\nfrom .step_prev"
},
{
"path": "api/models/control_net.py",
"chars": 324,
"preview": "from dataclasses import dataclass\nfrom typing import Tuple, List\nfrom numpy.typing import NDArray\n\n@dataclass\nclass Cont"
},
{
"path": "api/models/fix_it_error.py",
"chars": 1264,
"preview": "from typing import Callable, Any\nfrom .generation_arguments import GenerationArguments\nfrom dataclasses import dataclass"
},
{
"path": "api/models/generation_arguments.py",
"chars": 3345,
"preview": "from dataclasses import dataclass\nfrom typing import Tuple, List\nfrom ..models.task import Task\nfrom ..models.model impo"
},
{
"path": "api/models/generation_result.py",
"chars": 1971,
"preview": "from dataclasses import dataclass\nfrom numpy.typing import NDArray\nimport numpy as np\nimport math\n\n@dataclass\nclass Gene"
},
{
"path": "api/models/model.py",
"chars": 105,
"preview": "from dataclasses import dataclass\n\n@dataclass\nclass Model:\n name: str\n description: str\n id: str"
},
{
"path": "api/models/prompt.py",
"chars": 150,
"preview": "from dataclasses import dataclass\nfrom typing import List\n\n@dataclass\nclass Prompt:\n positive: str | List[str]\n ne"
},
{
"path": "api/models/seamless_axes.py",
"chars": 2604,
"preview": "from enum import Enum\n\nclass SeamlessAxes(Enum):\n \"\"\"Unified handling of seamless axes.\n Can be converted from str"
},
{
"path": "api/models/step_preview_mode.py",
"chars": 192,
"preview": "import enum\n\nclass StepPreviewMode(enum.Enum):\n NONE = \"None\"\n FAST = \"Fast\"\n FAST_BATCH = \"Fast (Batch Tiled)\""
},
{
"path": "api/models/task.py",
"chars": 1735,
"preview": "from dataclasses import dataclass\nfrom typing import Tuple\nfrom numpy.typing import NDArray\nfrom enum import IntEnum\n\ncl"
},
{
"path": "builtin_presets/Debug.py",
"chars": 707,
"preview": "import bpy\nprompt = bpy.context.scene.dream_textures_prompt\n\nprompt.steps = 20\nprompt.cfg_scale = 7.5\nprompt.scheduler ="
},
{
"path": "builtin_presets/Final.py",
"chars": 703,
"preview": "import bpy\nprompt = bpy.context.scene.dream_textures_prompt\n\nprompt.steps = 50\nprompt.cfg_scale = 7.5\nprompt.scheduler ="
},
{
"path": "builtin_presets/Preview.py",
"chars": 703,
"preview": "import bpy\nprompt = bpy.context.scene.dream_textures_prompt\n\nprompt.steps = 20\nprompt.cfg_scale = 7.5\nprompt.scheduler ="
},
{
"path": "classes.py",
"chars": 2630,
"preview": "from .operators.install_dependencies import InstallDependencies, UninstallDependencies\nfrom .operators.open_latest_versi"
},
{
"path": "community_backends/test.py",
"chars": 1049,
"preview": "bl_info = {\n \"name\": \"Test Backend\",\n \"blender\": (3, 1, 0),\n \"category\": \"Paint\",\n}\n\nimport bpy\nfrom typing imp"
},
{
"path": "diffusers_backend.py",
"chars": 17167,
"preview": "import bpy\nfrom bpy.props import FloatProperty, IntProperty, EnumProperty, BoolProperty\nfrom typing import List\n\nfrom .a"
},
{
"path": "docs/AI_UPSCALING.md",
"chars": 1307,
"preview": "# AI Upscaling\nUse the Stable Diffusion upscaler to increase images 4x in size while retaining detail. You can guide the"
},
{
"path": "docs/DEVELOPMENT_ENVIRONMENT.md",
"chars": 4652,
"preview": "# Setting Up a Development Environment\n\nWith the following steps, you can start contributing to Dream Textures.\n\nThese s"
},
{
"path": "docs/HISTORY.md",
"chars": 869,
"preview": "# History\nEach time you generate, the full configuration is saved to the *History* panel. You can recall any previous ge"
},
{
"path": "docs/IMAGE_GENERATION.md",
"chars": 4936,
"preview": "# Image Generation\n1. To open Dream Textures, go to an Image Editor or Shader Editor\n1. Ensure the sidebar is visible by"
},
{
"path": "docs/INPAINT_OUTPAINT.md",
"chars": 3226,
"preview": "# Inpaint/Outpaint\n\nThis guide shows how to use both [inpainting](#inpainting) and [outpainting](#outpainting).\n\n> For b"
},
{
"path": "docs/RENDER_PASS.md",
"chars": 2995,
"preview": "# Render Pass\nA custom 'Dream Textures' render pass is available for Cycles. This allows you to run Dream Textures on th"
},
{
"path": "docs/SETUP.md",
"chars": 4400,
"preview": "# Setting Up\nGetting up and running is easy. Make sure you have several GBs of storage free, as the model weights and ad"
},
{
"path": "docs/TEXTURE_PROJECTION.md",
"chars": 2620,
"preview": "# Texture Projection\n\nUsing depth to image, Dream Textures is able to texture entire scenes automatically with a simple "
},
{
"path": "docs/assets/banner_image_prompt.json",
"chars": 1675,
"preview": "{\n \"prompt_structure\": \"concept_art\",\n \"use_negative_prompt\": true,\n \"negative_prompt\": \"person dragon bird oce"
},
{
"path": "engine/__init__.py",
"chars": 6883,
"preview": "from .engine import *\nfrom .node_tree import *\nfrom .node_executor import *\nfrom .node import *\nfrom .nodes.input_nodes "
},
{
"path": "engine/annotations/ade20k.py",
"chars": 18319,
"preview": "import bpy\nimport gpu\nfrom gpu_extras.batch import batch_for_shader\nimport numpy as np\nimport threading\nfrom .compat imp"
},
{
"path": "engine/annotations/compat.py",
"chars": 204,
"preview": "import bpy\n\nUNIFORM_COLOR = 'UNIFORM_COLOR' if bpy.app.version >= (3, 4, 0) else '3D_UNIFORM_COLOR'\n\"\"\"\n2D_ and 3D_ pref"
},
{
"path": "engine/annotations/depth.py",
"chars": 3546,
"preview": "import bpy\nimport gpu\nfrom gpu_extras.batch import batch_for_shader\nimport numpy as np\nimport threading\nfrom .compat imp"
},
{
"path": "engine/annotations/normal.py",
"chars": 5194,
"preview": "import bpy\nimport gpu\nfrom gpu_extras.batch import batch_for_shader\nimport bmesh\nimport numpy as np\nimport threading\n\nde"
},
{
"path": "engine/annotations/openpose.py",
"chars": 11253,
"preview": "import bpy\nimport bpy_extras\nimport gpu\nfrom gpu_extras.batch import batch_for_shader\nimport mathutils\nimport numpy as n"
},
{
"path": "engine/annotations/viewport.py",
"chars": 1912,
"preview": "import bpy\nimport gpu\nimport numpy as np\nimport threading\n\ndef render_viewport_color(context, width=None, height=None, m"
},
{
"path": "engine/engine.py",
"chars": 12462,
"preview": "import bpy\nimport gpu\nfrom bl_ui.properties_render import RenderButtonsPanel\nfrom bl_ui.properties_output import RenderO"
},
{
"path": "engine/node.py",
"chars": 204,
"preview": "import bpy\nfrom .node_tree import DreamTexturesNodeTree\n\nclass DreamTexturesNode(bpy.types.Node):\n @classmethod\n d"
},
{
"path": "engine/node_executor.py",
"chars": 3241,
"preview": "import bpy\n# from dream_textures.engine import node_executor\n# node_executor.execute(bpy.data.node_groups[\"NodeTree\"], b"
},
{
"path": "engine/node_tree.py",
"chars": 344,
"preview": "import bpy\n\nclass DreamTexturesNodeTree(bpy.types.NodeTree):\n bl_idname = \"DreamTexturesNodeTree\"\n bl_label = \"Dre"
},
{
"path": "engine/nodes/annotation_nodes.py",
"chars": 4094,
"preview": "import bpy\nfrom ..node import DreamTexturesNode\nfrom ..annotations import depth\nfrom ..annotations import normal\nfrom .."
},
{
"path": "engine/nodes/input_nodes.py",
"chars": 3546,
"preview": "import bpy\nimport gpu\nfrom gpu_extras.batch import batch_for_shader\nimport numpy as np\nfrom ..node import DreamTexturesN"
},
{
"path": "engine/nodes/pipeline_nodes.py",
"chars": 9177,
"preview": "import bpy\nimport numpy as np\nfrom dataclasses import dataclass\nfrom typing import Any, List\nimport enum\nfrom ..node imp"
},
{
"path": "engine/nodes/utility_nodes.py",
"chars": 10942,
"preview": "import bpy\nimport numpy as np\nimport random\nfrom ..node import DreamTexturesNode\nfrom ...property_groups.dream_prompt im"
},
{
"path": "generator_process/__init__.py",
"chars": 3138,
"preview": "from typing import Callable\n\nfrom .actor import Actor, is_actor_process\n\nclass RunInSubprocess(Exception):\n \"\"\"\n D"
},
{
"path": "generator_process/actions/choose_device.py",
"chars": 575,
"preview": "import importlib.util\nimport sys\n\ndef choose_device(self, optimizations) -> str:\n \"\"\"\n Automatically select which "
},
{
"path": "generator_process/actions/control_net.py",
"chars": 7556,
"preview": "from typing import Union, Generator, Callable, List, Optional, Dict, Any\nfrom contextlib import nullcontext\n\nimport nump"
},
{
"path": "generator_process/actions/controlnet_aux.py",
"chars": 691,
"preview": "import numpy as np\nfrom numpy.typing import NDArray\nfrom ..models.optimizations import Optimizations\nfrom ...image_utils"
},
{
"path": "generator_process/actions/convert_original_stable_diffusion_to_diffusers.py",
"chars": 2710,
"preview": "import os\n\nfrom .huggingface_hub import DownloadStatus\nfrom ..future import Future\nfrom ..models import ModelConfig\n\n\nde"
},
{
"path": "generator_process/actions/depth_to_image.py",
"chars": 18007,
"preview": "from typing import Union, Generator, Callable, List, Optional\nimport os\nfrom contextlib import nullcontext\n\nimport numpy"
},
{
"path": "generator_process/actions/detect_seamless/__init__.py",
"chars": 3818,
"preview": "from enum import Enum\n\nimport numpy as np\nfrom numpy.typing import NDArray\n\nfrom ....api.models.seamless_axes import Sea"
},
{
"path": "generator_process/actions/huggingface_hub.py",
"chars": 7029,
"preview": "from dataclasses import dataclass\nimport os\nfrom pathlib import Path\nfrom typing import Dict, List, Optional, Union, Gen"
},
{
"path": "generator_process/actions/image_to_image.py",
"chars": 3532,
"preview": "from typing import Union, Generator, Callable, List, Optional\nimport os\nfrom contextlib import nullcontext\n\nfrom numpy.t"
},
{
"path": "generator_process/actions/inpaint.py",
"chars": 4695,
"preview": "from typing import Union, Generator, Callable, List, Optional\nimport os\nfrom contextlib import nullcontext\nimport numpy "
},
{
"path": "generator_process/actions/load_model.py",
"chars": 9809,
"preview": "import gc\nimport logging\nimport os\nfrom ..models import Checkpoint, ModelConfig, Scheduler\n\nlogger = logging.getLogger(_"
},
{
"path": "generator_process/actions/outpaint.py",
"chars": 2347,
"preview": "from typing import Tuple, Generator\nimport numpy as np\nfrom ..future import Future\nfrom ...api.models.generation_result "
},
{
"path": "generator_process/actions/prompt_to_image.py",
"chars": 7889,
"preview": "import functools\nfrom typing import Generator\nfrom contextlib import nullcontext\n\nimport numpy as np\nimport random\nfrom "
},
{
"path": "generator_process/actions/upscale.py",
"chars": 3171,
"preview": "import numpy as np\nfrom .prompt_to_image import Optimizations, Scheduler, StepPreviewMode, _configure_model_padding\nfrom"
},
{
"path": "generator_process/actor.py",
"chars": 11042,
"preview": "from multiprocessing import Queue, Lock, current_process, get_context\nimport multiprocessing.synchronize\nimport enum\nimp"
},
{
"path": "generator_process/block_in_use.py",
"chars": 620,
"preview": "def block_in_use(func):\n def block(self, *args, **kwargs):\n if self.in_use:\n raise RuntimeError(f\"C"
},
{
"path": "generator_process/directml_patches.py",
"chars": 5194,
"preview": "import functools\nimport gc\n\nimport torch\nfrom torch import Tensor\n\nactive_dml_patches: list | None = None\n\n\ndef pad(inpu"
},
{
"path": "generator_process/future.py",
"chars": 4479,
"preview": "import functools\nimport threading\nfrom typing import Callable, Any, MutableSet\n\nclass Future:\n \"\"\"\n Object that re"
},
{
"path": "generator_process/models/__init__.py",
"chars": 201,
"preview": "from .checkpoint import *\nfrom .image_generation_result import *\nfrom .model_config import *\nfrom .model_type import *\nf"
},
{
"path": "generator_process/models/checkpoint.py",
"chars": 168,
"preview": "from dataclasses import dataclass\n\nfrom .model_config import ModelConfig\n\n\n@dataclass(frozen=True)\nclass Checkpoint:\n "
},
{
"path": "generator_process/models/image_generation_result.py",
"chars": 3518,
"preview": "from ...api.models.step_preview_mode import StepPreviewMode\nfrom ...api.models.generation_result import GenerationResult"
},
{
"path": "generator_process/models/model_config.py",
"chars": 2713,
"preview": "import enum\n\nfrom ...absolute_path import absolute_path\n\n\nclass ModelConfig(enum.Enum):\n AUTO_DETECT = \"auto-detect\"\n"
},
{
"path": "generator_process/models/model_type.py",
"chars": 2985,
"preview": "import enum\n\nfrom ...api.models.task import *\nfrom .model_config import ModelConfig\n\n\nclass ModelType(enum.IntEnum):\n "
},
{
"path": "generator_process/models/optimizations.py",
"chars": 7159,
"preview": "from enum import Enum\nfrom typing import Annotated, Union, _AnnotatedAlias\nimport functools\nimport os\nimport sys\nfrom da"
},
{
"path": "generator_process/models/scheduler.py",
"chars": 3002,
"preview": "import enum\n\nclass Scheduler(enum.Enum):\n DDIM = \"DDIM\"\n DDPM = \"DDPM\"\n DEIS_MULTISTEP = \"DEIS Multistep\"\n D"
},
{
"path": "generator_process/models/upscale_tiler.py",
"chars": 11990,
"preview": "import math\nfrom typing import Optional\n\nimport numpy as np\nfrom ..actions.detect_seamless import SeamlessAxes\nfrom nump"
},
{
"path": "image_utils.py",
"chars": 33906,
"preview": "import importlib.util\nimport os\nimport sys\nfrom os import PathLike\nfrom typing import Tuple, Literal, Union, TYPE_CHECKI"
},
{
"path": "operators/dream_texture.py",
"chars": 12783,
"preview": "import bpy\nimport hashlib\nimport numpy as np\nfrom typing import List, Literal\n\nfrom .notify_result import NotifyResult\nf"
},
{
"path": "operators/inpaint_area_brush.py",
"chars": 1679,
"preview": "import bpy\n\nreset_blend_mode = 'MIX'\nreset_curve_preset = 'CUSTOM'\nreset_strength = 1.0\nclass InpaintAreaBrushActivated("
},
{
"path": "operators/install_dependencies.py",
"chars": 7699,
"preview": "import bpy\nimport os\nimport site\nimport sys\nimport sysconfig\nimport subprocess\nimport requests\nimport tarfile\nfrom enum "
},
{
"path": "operators/notify_result.py",
"chars": 845,
"preview": "import bpy\nimport os\nimport sys\n\nclass NotifyResult(bpy.types.Operator):\n bl_idname = \"shade.dream_textures_notify_re"
},
{
"path": "operators/open_latest_version.py",
"chars": 1236,
"preview": "import requests\nimport bpy\nimport webbrowser\nfrom ..version import VERSION, version_tag, version_tuple\n\nREPO_OWNER = \"ca"
},
{
"path": "operators/project.py",
"chars": 20850,
"preview": "import bpy\nimport gpu\nimport gpu.texture\nfrom gpu_extras.batch import batch_for_shader\nimport bmesh\nfrom bpy_extras impo"
},
{
"path": "operators/upscale.py",
"chars": 5593,
"preview": "import bpy\nimport numpy as np\nfrom typing import List, Literal\nfrom .. import api\nfrom ..prompt_engineering import custo"
},
{
"path": "operators/view_history.py",
"chars": 6267,
"preview": "import bpy\nfrom bpy_extras.io_utils import ImportHelper, ExportHelper\nimport json\nimport os\nfrom ..property_groups.dream"
},
{
"path": "preferences.py",
"chars": 20950,
"preview": "import bpy\nfrom bpy.props import CollectionProperty, StringProperty\nfrom bpy_extras.io_utils import ImportHelper\nimport "
},
{
"path": "prompt_engineering.py",
"chars": 4166,
"preview": "from collections import namedtuple\n\nPromptToken = namedtuple('PromptToken', ['id', 'label', 'values'])\nPromptStructure ="
},
{
"path": "property_groups/control_net.py",
"chars": 4851,
"preview": "import bpy\nfrom bpy.props import FloatProperty, EnumProperty, PointerProperty, IntProperty, BoolProperty\n\nfrom .. import"
},
{
"path": "property_groups/dream_prompt.py",
"chars": 14249,
"preview": "import bpy\nfrom bpy.props import FloatProperty, IntProperty, EnumProperty, BoolProperty, StringProperty, IntVectorProper"
},
{
"path": "property_groups/seamless_result.py",
"chars": 2571,
"preview": "import bpy\n\nimport numpy as np\nfrom ..generator_process.actions.detect_seamless import SeamlessAxes\nfrom ..generator_pro"
},
{
"path": "realtime_viewport.py",
"chars": 6905,
"preview": "# Realtime Viewport is still under development, and is not currently used.\nimport bpy\nimport cycles\nimport time\nimport t"
},
{
"path": "render_pass.py",
"chars": 6457,
"preview": "import bpy\nimport cycles\nimport numpy as np\nimport os\nfrom typing import List\nimport threading\nfrom .generator_process i"
},
{
"path": "requirements/linux-rocm.txt",
"chars": 331,
"preview": "diffusers==0.27.2\ninvisible-watermark\ntransformers\naccelerate\nhuggingface_hub\ncontrolnet-aux==0.0.7\n\n--extra-index-url h"
},
{
"path": "requirements/mac-mps-cpu.txt",
"chars": 278,
"preview": "diffusers==0.27.2\ninvisible-watermark\ntransformers\naccelerate\nhuggingface_hub>=0.19.3\ncontrolnet-aux==0.0.7\n\ntorch==2.3."
},
{
"path": "requirements/win-dml.txt",
"chars": 285,
"preview": "diffusers==0.27.2\ninvisible-watermark\ntransformers\naccelerate\nhuggingface_hub\ncontrolnet-aux==0.0.7\n\ntorch-directml\ntorc"
},
{
"path": "requirements/win-linux-cuda.txt",
"chars": 339,
"preview": "diffusers==0.27.2\ninvisible-watermark\ntransformers\naccelerate\nhuggingface_hub\ncontrolnet-aux==0.0.7\n\n--extra-index-url h"
},
{
"path": "scripts/train_detect_seamless.py",
"chars": 13826,
"preview": "\"\"\"\nIt's recommended to copy this script to its own project folder to\nkeep it with your own image samples and trained mo"
},
{
"path": "scripts/zip_dependencies.py",
"chars": 685,
"preview": "import shutil\nimport zipfile\nfrom pathlib import Path\n\n\ndef main():\n root = Path(__file__).parent.parent\n deps = r"
},
{
"path": "sd_configs/cldm_v15.yaml",
"chars": 1949,
"preview": "model:\n target: cldm.cldm.ControlLDM\n params:\n linear_start: 0.00085\n linear_end: 0.0120\n num_timesteps_cond:"
},
{
"path": "sd_configs/cldm_v21.yaml",
"chars": 2216,
"preview": "model:\n target: cldm.cldm.ControlLDM\n params:\n linear_start: 0.00085\n linear_end: 0.0120\n num_timesteps_cond:"
},
{
"path": "sd_configs/sd_xl_base.yaml",
"chars": 3247,
"preview": "model:\n target: sgm.models.diffusion.DiffusionEngine\n params:\n scale_factor: 0.13025\n disable_first_stage_autoca"
},
{
"path": "sd_configs/sd_xl_refiner.yaml",
"chars": 2948,
"preview": "model:\n target: sgm.models.diffusion.DiffusionEngine\n params:\n scale_factor: 0.13025\n disable_first_stage_autoca"
},
{
"path": "sd_configs/v1-inference.yaml",
"chars": 1873,
"preview": "model:\n base_learning_rate: 1.0e-04\n target: ldm.models.diffusion.ddpm.LatentDiffusion\n params:\n linear_start: 0.0"
},
{
"path": "sd_configs/v2-inference-v.yaml",
"chars": 1815,
"preview": "model:\n base_learning_rate: 1.0e-4\n target: ldm.models.diffusion.ddpm.LatentDiffusion\n params:\n parameterization: "
},
{
"path": "sd_configs/v2-inference.yaml",
"chars": 1789,
"preview": "model:\n base_learning_rate: 1.0e-4\n target: ldm.models.diffusion.ddpm.LatentDiffusion\n params:\n linear_start: 0.00"
},
{
"path": "sd_configs/v2-inpainting-inference.yaml",
"chars": 4450,
"preview": "model:\n base_learning_rate: 5.0e-05\n target: ldm.models.diffusion.ddpm.LatentInpaintDiffusion\n params:\n linear_sta"
},
{
"path": "sd_configs/v2-midas-inference.yaml",
"chars": 1869,
"preview": "model:\n base_learning_rate: 5.0e-07\n target: ldm.models.diffusion.ddpm.LatentDepth2ImageDiffusion\n params:\n linear"
},
{
"path": "tools.py",
"chars": 93,
"preview": "from .operators.inpaint_area_brush import InpaintAreaBrush\n\nTOOLS = (\n InpaintAreaBrush,\n)"
},
{
"path": "ui/panels/dream_texture.py",
"chars": 17294,
"preview": "import bpy\nfrom bpy.types import Panel\nfrom ..presets import DREAM_PT_AdvancedPresets\nfrom ...prompt_engineering import "
},
{
"path": "ui/panels/history.py",
"chars": 1866,
"preview": "import bpy\nfrom bpy.types import Panel\nfrom ...prompt_engineering import *\nfrom ...operators.dream_texture import DreamT"
},
{
"path": "ui/panels/render_properties.py",
"chars": 3484,
"preview": "import bpy\nfrom .dream_texture import create_panel, prompt_panel, advanced_panel\nfrom ...property_groups.dream_prompt im"
},
{
"path": "ui/panels/upscaling.py",
"chars": 5437,
"preview": "from bpy.types import Panel\nfrom ...prompt_engineering import *\nfrom ...operators.upscale import Upscale, get_source_ima"
},
{
"path": "ui/presets.py",
"chars": 3053,
"preview": "import bpy\nfrom bpy.types import Panel, Operator, Menu\nfrom bl_operators.presets import AddPresetBase\nfrom bl_ui.utils i"
},
{
"path": "ui/space_types.py",
"chars": 45,
"preview": "SPACE_TYPES = {'IMAGE_EDITOR', 'NODE_EDITOR'}"
},
{
"path": "version.py",
"chars": 180,
"preview": "VERSION = (0, 4, 1)\ndef version_tag(version):\n return f\"{version[0]}.{version[1]}.{version[2]}\"\n\ndef version_tuple(ta"
}
]
// ... and 1 more files (download for full content)
About this extraction
This page contains the full source code of the carson-katri/dream-textures GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 120 files (551.0 KB), approximately 132.4k tokens, and a symbol index with 573 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.