@@ -832,6 +832,8 @@ auto SContext::genMaterial(const CElementBSDF* bsdf, system::ISystem* debugFileW
832832 btdfH = brdf->lhs ;
833833 }
834834 leaf->btdf = mul (btdfH,factorH);
835+ // By default, all non-transmissive scattering models in Mitsuba are one-sided = all transmissive are two sided
836+ leaf->brdfBottom = brdfH;
835837 }
836838 break ;
837839 }
@@ -882,6 +884,8 @@ auto SContext::genMaterial(const CElementBSDF* bsdf, system::ISystem* debugFileW
882884 }
883885 leaf->brdfTop = diffTransH;
884886 leaf->btdf = diffTransH;
887+ // By default, all non-transmissive scattering models in Mitsuba are one-sided = all transmissive are two sided
888+ leaf->brdfBottom = diffTransH;
885889 break ;
886890 }
887891 default :
@@ -891,32 +895,21 @@ auto SContext::genMaterial(const CElementBSDF* bsdf, system::ISystem* debugFileW
891895 }
892896 leaf = frontPool.deref (retval);
893897 assert (leaf->brdfTop );
894- assert (!leaf->brdfBottom );
895898 return retval;
896899 };
897900
898901 // Post-order Depth First Traversal (create children first, then create parent)
899902 struct SStackEntry
900903 {
901- enum class ExpectedNodeType : uint64_t
902- {
903- Layer,
904- Count
905- };
906904 const CElementBSDF* bsdf;
907- ExpectedNodeType expectedNodeType : 2 = ExpectedNodeType::Layer;
908905 uint64_t visited : 1 = false ;
909- uint64_t unused : 61 = 0 ;
906+ uint64_t unused : 63 = 0 ;
910907 };
911908 core::vector<SStackEntry> stack;
912909 stack.reserve (128 );
913910 stack.emplace_back () = {.bsdf =bsdf};
914911 // for the static casts of handles
915- using block_allocator_t = frontend_ir_t ::obj_pool_type::mem_pool_type::block_allocator_type;
916- using node_t = frontend_ir_t ::typed_pointer_type<frontend_ir_t ::INode>;
917- using expected_e = SStackEntry::ExpectedNodeType;
918- const node_t errorNodes[size_t (expected_e::Count)] = {errorMaterial}; // TODO: {errorFactor,errorBRDF,errorLayer}
919- core::unordered_map<const CElementBSDF*,node_t > localCache;
912+ core::unordered_map<const CElementBSDF*,material_t > localCache;
920913 localCache.reserve (16 );
921914 //
922915 while (!stack.empty ())
@@ -935,49 +928,32 @@ auto SContext::genMaterial(const CElementBSDF* bsdf, system::ISystem* debugFileW
935928 {
936929 case CElementBSDF::COATING: [[fallthrough]];
937930 case CElementBSDF::ROUGHCOATING: [[fallthrough]];
931+ case CElementBSDF::BUMPMAP: [[fallthrough]];
932+ case CElementBSDF::NORMALMAP: [[fallthrough]];
938933 case CElementBSDF::MASK:
939- {
940934 assert (meta_common.childCount ==1 );
941- stack.emplace_back () = {.bsdf =meta_common.bsdf [0 ],.expectedNodeType =expected_e::Layer};
942- break ;
943- }
944- case CElementBSDF::BUMPMAP:
945- {
946- assert (false ); // unimplemented
947- break ;
948- }
949- case CElementBSDF::NORMALMAP:
950- {
951- assert (false ); // unimplemented
952935 break ;
953- }
954936 case CElementBSDF::MIXTURE_BSDF:
955- {
956- assert (false ); // unimplemented
957937 break ;
958- }
959938 case CElementBSDF::BLEND_BSDF:
960- {
961- assert (false ); // unimplemented
939+ assert (meta_common.childCount ==2 );
962940 break ;
963- }
964941 case CElementBSDF::TWO_SIDED:
965- {
966942 assert (meta_common.childCount <=2 );
967- stack.emplace_back () = {.bsdf =meta_common.bsdf [0 ],.expectedNodeType =expected_e::Layer};
968- assert (false ); // unimplemented
969943 break ;
970- }
971944 default :
972945 assert (false ); // we shouldn't get this case here
973946 break ;
974947 }
948+ stack.emplace_back () = {.bsdf =meta_common.bsdf [0 ]};
949+ for (decltype (meta_common.childCount ) i=1 ; i<meta_common.childCount ; i++)
950+ stack.emplace_back () = {.bsdf =meta_common.bsdf [i]};
975951 }
976952 entry.visited = true ;
977953 }
978954 else
979955 {
980- node_t newNodeH = {};
956+ material_t newNodeH = {};
981957 if (_bsdf->isMeta ())
982958 {
983959 switch (_bsdf->type )
@@ -992,7 +968,7 @@ auto SContext::genMaterial(const CElementBSDF* bsdf, system::ISystem* debugFileW
992968 // BTDF thats transmission with absorption
993969 // TODO
994970 // attach leaf as layer
995- coating->coated = block_allocator_t ::_static_cast< frontend_ir_t ::CLayer>( localCache[_bsdf->mask .bsdf [0 ]]);
971+ coating->coated = localCache[_bsdf->mask .bsdf [0 ]]. _const_cast ( );
996972 newNodeH = coatingH;
997973 break ;
998974 }
@@ -1001,8 +977,8 @@ auto SContext::genMaterial(const CElementBSDF* bsdf, system::ISystem* debugFileW
1001977 const auto maskH = frontPool.emplace <frontend_ir_t ::CLayer>();
1002978 auto * const mask = frontPool.deref (maskH);
1003979 //
1004- const auto nestedH = block_allocator_t ::_static_cast< frontend_ir_t ::CLayer>( localCache[_bsdf->mask .bsdf [0 ]]) ;
1005- auto * const nested = frontPool.deref (nestedH);
980+ const auto nestedH = localCache[_bsdf->mask .bsdf [0 ]];
981+ const auto * const nested = frontPool.deref (nestedH);
1006982 assert (nested && nested->brdfTop );
1007983 const auto opacityH = createFactorNode (_bsdf->mask .opacity ,ECommonDebug::Opacity);
1008984 mask->brdfTop = mul (nested->brdfTop ,opacityH);
@@ -1037,8 +1013,39 @@ auto SContext::genMaterial(const CElementBSDF* bsdf, system::ISystem* debugFileW
10371013 }
10381014 case CElementBSDF::TWO_SIDED:
10391015 {
1040- // create a copy of the layer, with different settings (don't want to disturb the original)
1041- // 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
1016+ const auto origFrontH = localCache[_bsdf->mask .bsdf [0 ]];
1017+ const auto * const origFront = frontPool.deref (origFrontH);
1018+ #if 0
1019+ // attach the original on both sides
1020+ if (_bsdf->twosided.childCount==1)
1021+ {
1022+ // get to the bottom layer
1023+ auto lastLayerH = origTopH;
1024+ while (lastLayerH)
1025+ {
1026+ const auto* const layer = frontPool.deref(lastLayerH);
1027+ lastLayerH = layer->coated;
1028+ }
1029+ // do we even have a non-twosided material?
1030+ //
1031+
1032+ // create a copy of the layer, with different settings (don't want to disturb the original)
1033+ const auto twoSidedH = frontPool.emplace<frontend_ir_t::CLayer>();
1034+ auto* const twoSided = frontPool.deref(twoSidedH);
1035+ if (origTop->coated)
1036+ {
1037+ //
1038+ }
1039+ else
1040+ //
1041+ twoSided->brdfBottom = origTop->brdfTop;
1042+ }
1043+ else
1044+ {
1045+ // glue a copy of the second child in reverse from its last layer to the front while reciprocating
1046+ const auto origBottomH = localCache[_bsdf->mask.bsdf[1]];
1047+ }
1048+ #endif
10421049 assert (false ); // unimplemented
10431050 break ;
10441051 }
@@ -1050,7 +1057,7 @@ auto SContext::genMaterial(const CElementBSDF* bsdf, system::ISystem* debugFileW
10501057 else
10511058 newNodeH = createMistubaLeaf (_bsdf);
10521059 if (!newNodeH)
1053- newNodeH = errorNodes[ size_t (entry. expectedNodeType )] ;
1060+ newNodeH = errorMaterial ;
10541061 localCache[_bsdf] = newNodeH;
10551062 stack.pop_back ();
10561063 }
@@ -1059,7 +1066,7 @@ auto SContext::genMaterial(const CElementBSDF* bsdf, system::ISystem* debugFileW
10591066 const auto found = localCache.find (bsdf);
10601067 if (found!=localCache.end ())
10611068 return errorMaterial;
1062- const auto rootH = block_allocator_t ::_static_cast< frontend_ir_t ::CLayer>( found->second );
1069+ const auto rootH = found->second . _const_cast ( );
10631070 if (!rootH)
10641071 return errorMaterial;
10651072 auto * const root = frontPool.deref (rootH);
0 commit comments