@@ -839,11 +839,11 @@ auto SContext::genMaterial(const CElementBSDF* bsdf, system::ISystem* debugFileW
839839 }
840840 case CElementBSDF::PHONG:
841841 logger.log (" Failed to Create a Phong BxDF for Material for %s, Phong is Unsupported" ,LoggerError,debugName.c_str ());
842- leaf-> brdfTop = unsupportedPhong;
842+ retval = unsupportedPhong. _const_cast () ;
843843 break ;
844844 case CElementBSDF::WARD:
845845 logger.log (" Failed to Create a Ward BxDF for Material for %s, Ward is Unsupported" ,LoggerError,debugName.c_str ());
846- leaf-> brdfTop = unsupportedWard;
846+ retval = unsupportedWard. _const_cast () ;
847847 break ;
848848 case CElementBSDF::DIFFUSE_TRANSMITTER:
849849 {
@@ -865,41 +865,85 @@ auto SContext::genMaterial(const CElementBSDF* bsdf, system::ISystem* debugFileW
865865 }
866866 default :
867867 assert (false ); // we shouldn't get this case here
868- return {} ;
868+ return errorMaterial. _const_cast () ;
869869 }
870870 assert (!leaf->brdfBottom );
871871 return retval;
872872 };
873873
874874 // Post-order Depth First Traversal (create children first, then create parent)
875- if (bsdf->isMeta ()) // TODO: temporary
876- return {};
877- const auto rootH = createMistubaLeaf (bsdf);
878- if (!rootH)
879- return {};
880- // material compiler is designed so that we don't need to reciprocate the BRDFs as we go through layers as long as observer is still on the same side
881-
882- #if 0
883- core::stack<const CElementBSDF*> stack;
884- stack.push(bsdf);
885- while (!stack.empty())
875+ struct SStackEntry
886876 {
887- auto* bsdf = stack.top();
888- stack.pop();
889- //
890- }
891- #endif
892-
877+ const CElementBSDF* bsdf;
878+ uint64_t visited : 1 = false ;
879+ uint64_t expectedNodeType : 2 = false ;
880+ uint64_t unused : 61 = false ;
881+ };
882+ core::vector<SStackEntry> stack;
883+ stack.reserve (128 );
884+ stack.emplace_back () = {
885+ .bsdf = bsdf
886+ };
887+ // for the static casts of handles
888+ using block_allocator_t = frontend_ir_t ::obj_pool_type::mem_pool_type::block_allocator_type;
889+ using node_t = frontend_ir_t ::typed_pointer_type<frontend_ir_t ::INode>;
890+ core::unordered_map<const CElementBSDF*,node_t > localCache;
891+ while (!stack.front ().visited )
893892 {
894- auto * const root = frontPool.deref (rootH);
895- root->debugInfo = frontPool.emplace <frontend_ir_t ::CDebugInfo>(debugName);
893+ const auto entry = stack.back ();
894+ assert (entry.bsdf );
895+ if (!entry.visited )
896+ {
897+ node_t newNodeH = {}; // TODO: {errorFactor,errorBRDF,errorLayer}[entry.expectedNodeType];
898+ if (entry.bsdf ->isMeta ())
899+ {
900+ return errorMaterial;// temporary
901+ switch (entry.bsdf ->type )
902+ {
903+ case CElementBSDF::MASK:
904+ {
905+ const auto maskH = createFactorNode (entry.bsdf ->mask .opacity ,ECommonDebug::Opacity);
906+ auto * const mask = frontPool.deref (maskH);
907+ // mask->lhs = ;
908+ newNodeH = maskH;
909+ break ;
910+ }
911+ // case CElementBSDF::TWO_SIDED:
912+ // material compiler is designed so that we don't need to reciprocate the BRDFs as we go through layers as long as observer is still on the same side
913+ // break;
914+ default :
915+ assert (false ); // we shouldn't get this case here
916+ break ;
917+ }
918+ }
919+ else
920+ {
921+ newNodeH = createMistubaLeaf (entry.bsdf );
922+ // have to make it available somehow for parent
923+ }
924+ localCache[entry.bsdf ] = newNodeH;
925+ stack.back ().visited = true ;
926+ }
927+ else
928+ {
929+ stack.pop_back ();
930+ }
896931 }
897932
933+ const auto found = localCache.find (bsdf);
934+ if (found!=localCache.end ())
935+ return errorMaterial;
936+ const auto rootH = block_allocator_t ::_static_cast<frontend_ir_t ::CLayer>(found->second );
937+ if (!rootH)
938+ return errorMaterial;
939+ auto * const root = frontPool.deref (rootH);
940+ root->debugInfo = frontPool.emplace <frontend_ir_t ::CDebugInfo>(debugName);
941+
898942 const bool success = frontIR->addMaterial (rootH,inner.params .logger );
899943 if (!success)
900944 {
901945 logger.log (" Failed to add Material for %s" ,LoggerError,debugName.c_str ());
902- return {} ;
946+ return errorMaterial ;
903947 }
904948 else if (debugFileWriter)
905949 {
@@ -1043,6 +1087,7 @@ SContext::SContext(
10431087 root->debugInfo = frontPool.emplace <frontend_ir_t ::CDebugInfo>(debugName);
10441088 return rootH;
10451089 };
1090+ errorMaterial = constructUnsupported (" ERROR Layer" );
10461091 unsupportedPhong = constructUnsupported (" UNSUPPORTED Phong" );
10471092 unsupportedWard = constructUnsupported (" UNSUPPORTED Ward" );
10481093
@@ -1051,6 +1096,7 @@ SContext::SContext(
10511096 {
10521097#define ADD_DEBUG_NODE (NAME ) commonDebugNames[uint16_t (ECommonDebug::NAME)] = frontPool.emplace<frontend_ir_t ::CDebugInfo>(#NAME)
10531098 ADD_DEBUG_NODE (Albedo);
1099+ ADD_DEBUG_NODE (Opacity);
10541100 ADD_DEBUG_NODE (MitsubaExtraFactor);
10551101#undef ADD_DEBUG_NODE
10561102 }
0 commit comments