Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/render/graph.cpp
| Show All 11 Lines | |||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| * See the License for the specific language governing permissions and | * See the License for the specific language governing permissions and | ||||
| * limitations under the License. | * limitations under the License. | ||||
| */ | */ | ||||
| #include "attribute.h" | #include "attribute.h" | ||||
| #include "graph.h" | #include "graph.h" | ||||
| #include "nodes.h" | #include "nodes.h" | ||||
| #include "scene.h" | |||||
| #include "shader.h" | #include "shader.h" | ||||
| #include "constant_fold.h" | #include "constant_fold.h" | ||||
| #include "util_algorithm.h" | #include "util_algorithm.h" | ||||
| #include "util_debug.h" | #include "util_debug.h" | ||||
| #include "util_foreach.h" | #include "util_foreach.h" | ||||
| #include "util_queue.h" | #include "util_queue.h" | ||||
| #include "util_logging.h" | #include "util_logging.h" | ||||
| ▲ Show 20 Lines • Show All 162 Lines • ▼ Show 20 Lines | bool ShaderNode::equals(const ShaderNode& other) | ||||
| return true; | return true; | ||||
| } | } | ||||
| /* Graph */ | /* Graph */ | ||||
| ShaderGraph::ShaderGraph() | ShaderGraph::ShaderGraph() | ||||
| { | { | ||||
| finalized = false; | finalized = false; | ||||
| simplified = false; | |||||
| num_node_ids = 0; | num_node_ids = 0; | ||||
| add(new OutputNode()); | add(new OutputNode()); | ||||
| } | } | ||||
| ShaderGraph::~ShaderGraph() | ShaderGraph::~ShaderGraph() | ||||
| { | { | ||||
| clear_nodes(); | clear_nodes(); | ||||
| } | } | ||||
| ShaderNode *ShaderGraph::add(ShaderNode *node) | ShaderNode *ShaderGraph::add(ShaderNode *node) | ||||
| { | { | ||||
| assert(!finalized); | assert(!finalized); | ||||
| simplified = false; | |||||
sergey: Why that's needed here for `simplified` but not for `finalized`? | |||||
| node->id = num_node_ids++; | node->id = num_node_ids++; | ||||
| nodes.push_back(node); | nodes.push_back(node); | ||||
| return node; | return node; | ||||
| } | } | ||||
| OutputNode *ShaderGraph::output() | OutputNode *ShaderGraph::output() | ||||
| { | { | ||||
| return (OutputNode*)nodes.front(); | return (OutputNode*)nodes.front(); | ||||
| Show All 18 Lines | ShaderGraph *ShaderGraph::copy() | ||||
| return newgraph; | return newgraph; | ||||
| } | } | ||||
| void ShaderGraph::connect(ShaderOutput *from, ShaderInput *to) | void ShaderGraph::connect(ShaderOutput *from, ShaderInput *to) | ||||
| { | { | ||||
| assert(!finalized); | assert(!finalized); | ||||
| assert(from && to); | assert(from && to); | ||||
| simplified = false; | |||||
| if(to->link) { | if(to->link) { | ||||
| fprintf(stderr, "Cycles shader graph connect: input already connected.\n"); | fprintf(stderr, "Cycles shader graph connect: input already connected.\n"); | ||||
| return; | return; | ||||
| } | } | ||||
| if(from->type() != to->type()) { | if(from->type() != to->type()) { | ||||
| /* for closures we can't do automatic conversion */ | /* for closures we can't do automatic conversion */ | ||||
| Show All 16 Lines | else { | ||||
| to->link = from; | to->link = from; | ||||
| from->links.push_back(to); | from->links.push_back(to); | ||||
| } | } | ||||
| } | } | ||||
| void ShaderGraph::disconnect(ShaderOutput *from) | void ShaderGraph::disconnect(ShaderOutput *from) | ||||
| { | { | ||||
| assert(!finalized); | assert(!finalized); | ||||
| simplified = false; | |||||
| foreach(ShaderInput *sock, from->links) { | foreach(ShaderInput *sock, from->links) { | ||||
| sock->link = NULL; | sock->link = NULL; | ||||
| } | } | ||||
| from->links.clear(); | from->links.clear(); | ||||
| } | } | ||||
| void ShaderGraph::disconnect(ShaderInput *to) | void ShaderGraph::disconnect(ShaderInput *to) | ||||
| { | { | ||||
| assert(!finalized); | assert(!finalized); | ||||
| assert(to->link); | assert(to->link); | ||||
| simplified = false; | |||||
| ShaderOutput *from = to->link; | ShaderOutput *from = to->link; | ||||
| to->link = NULL; | to->link = NULL; | ||||
| from->links.erase(remove(from->links.begin(), from->links.end(), to), from->links.end()); | from->links.erase(remove(from->links.begin(), from->links.end(), to), from->links.end()); | ||||
| } | } | ||||
| void ShaderGraph::relink(ShaderNode *node, ShaderOutput *from, ShaderOutput *to) | void ShaderGraph::relink(ShaderNode *node, ShaderOutput *from, ShaderOutput *to) | ||||
| { | { | ||||
| simplified = false; | |||||
| /* Copy because disconnect modifies this list */ | /* Copy because disconnect modifies this list */ | ||||
| vector<ShaderInput*> outputs = from->links; | vector<ShaderInput*> outputs = from->links; | ||||
| /* Bypass node by moving all links from "from" to "to" */ | /* Bypass node by moving all links from "from" to "to" */ | ||||
| foreach(ShaderInput *sock, node->inputs) { | foreach(ShaderInput *sock, node->inputs) { | ||||
| if(sock->link) | if(sock->link) | ||||
| disconnect(sock); | disconnect(sock); | ||||
| } | } | ||||
| foreach(ShaderInput *sock, outputs) { | foreach(ShaderInput *sock, outputs) { | ||||
| disconnect(sock); | disconnect(sock); | ||||
| if(to) | if(to) | ||||
| connect(to, sock); | connect(to, sock); | ||||
| } | } | ||||
| } | } | ||||
| void ShaderGraph::simplify(Scene *scene) | |||||
| { | |||||
| if(!simplified) { | |||||
| default_inputs(scene->shader_manager->use_osl()); | |||||
| clean(scene); | |||||
| refine_bump_nodes(); | |||||
| simplified = true; | |||||
| } | |||||
| } | |||||
| void ShaderGraph::finalize(Scene *scene, | void ShaderGraph::finalize(Scene *scene, | ||||
| bool do_bump, | bool do_bump, | ||||
| bool do_osl, | |||||
| bool do_simplify, | bool do_simplify, | ||||
| bool bump_in_object_space) | bool bump_in_object_space) | ||||
| { | { | ||||
| /* before compiling, the shader graph may undergo a number of modifications. | /* before compiling, the shader graph may undergo a number of modifications. | ||||
| * currently we set default geometry shader inputs, and create automatic bump | * currently we set default geometry shader inputs, and create automatic bump | ||||
| * from displacement. a graph can be finalized only once, and should not be | * from displacement. a graph can be finalized only once, and should not be | ||||
| * modified afterwards. */ | * modified afterwards. */ | ||||
| if(!finalized) { | if(!finalized) { | ||||
| default_inputs(do_osl); | simplify(scene); | ||||
| clean(scene); | |||||
| refine_bump_nodes(); | |||||
| if(do_bump) | if(do_bump) | ||||
| bump_from_displacement(bump_in_object_space); | bump_from_displacement(bump_in_object_space); | ||||
| ShaderInput *surface_in = output()->input("Surface"); | ShaderInput *surface_in = output()->input("Surface"); | ||||
| ShaderInput *volume_in = output()->input("Volume"); | ShaderInput *volume_in = output()->input("Volume"); | ||||
| /* todo: make this work when surface and volume closures are tangled up */ | /* todo: make this work when surface and volume closures are tangled up */ | ||||
| ▲ Show 20 Lines • Show All 728 Lines • Show Last 20 Lines | |||||
Why that's needed here for simplified but not for finalized?