3737
3838#include < penumbra/penumbra.h>
3939
40+ #define PUMBRAIF
41+ #if defined PUMBRAIF
42+ #define PUMBRA ( m ) (Top.tp_pPumbra->m)
43+ #else
4044static Pumbra::Penumbra pumbra;
41-
45+ #define PUMBRA ( m ) (pumbra.m)
46+ #endif
4247
4348// /////////////////////////////////////////////////////////////////////////////
4449// overhang/fin shading
@@ -420,7 +425,7 @@ int SURFGEOMDET::gxd_SetupShading( // convert polygon to Penumbra format
420425 plg.push_back ( float ( p3[ iD]));
421426 }
422427 Pumbra::Surface pnSurf ( plg);
423- pnIdx = pumbra. addSurface ( pnSurf);
428+ pnIdx = PUMBRA ( addSurface ( pnSurf) );
424429 }
425430 return pnIdx;
426431} // SURFGEOMDET::gxd_SetupShading
@@ -583,12 +588,12 @@ int SURFGEOM::gx_CalcBeamShading( // beam shading for current hour
583588 slsdc ( azm, kPiOver2 -alt, dcSun);
584589 cosi = DotProd3 ( dcSrf, dcSun); // replace cosi with value
585590 // consistent with alt and azm
586- if (pumbra. setSunPosition ( azm, alt) != Pumbra::PN_SUCCESS)
591+ if (PUMBRA ( setSunPosition) ( azm, alt) != Pumbra::PN_SUCCESS)
587592 { cosi = fBeam = 0 .f ;
588593 sunupSrf = -1 ; // unexpected
589594 }
590595 else
591- { float PSSF = pumbra. calculatePSSF ( gx_pnIdx);
596+ { float PSSF = PUMBRA ( calculatePSSF) ( gx_pnIdx);
592597 fBeam = PSSF / (cosi*gx_area);
593598 if (fBeam > 1 .f )
594599 {
@@ -666,23 +671,130 @@ RC SHADEX::sx_CkF()
666671// /////////////////////////////////////////////////////////////////////////////
667672// TOPRAT interface to shading model
668673// /////////////////////////////////////////////////////////////////////////////
669- static void PemumbraMessageHandler (
674+ static void PenumbraMessageHandler (
670675 const int messageType,
671676 const std::string message,
672677 void * contextPtr)
673678{
674- contextPtr;
679+ // TOPRAT* pTop = (TOPRAT *) contextPtr;
675680
676- (messageType == Pumbra::MSG_ERR ? per : messageType == Pumbra::MSG_WARN ? pWarn : pInfo)
677- ( " Penumbra msg: %s" , message.c_str ());
681+ int erOp;
682+ const char * what;
683+ if (messageType == Pumbra::MSG_ERR)
684+ { erOp = ABT; // message / keypress / abort
685+ what = " error" ;
686+ }
687+ else if (messageType == Pumbra::MSG_WARN)
688+ { erOp = ERR; // message / keypress / continue
689+ what = " warning" ;
690+ }
691+ else
692+ { erOp = INF; // message / continue
693+ what = " info" ;
694+ }
695+ err (
696+ erOp | NOPREF, // do not prepend "Error:"
697+ " Shading %s: %s" , what, message.c_str ());
678698
679699} // penumbraMessageHandler
680700// -----------------------------------------------------------------------------
701+ RC TOPRAT::tp_PumbraInit ()
702+ { RC rc = RCOK;
703+ if (!tp_pPumbra)
704+ { const int size = 512 ; // context size (=# of pixels)
705+ tp_pPumbra = new Pumbra::Penumbra ( PenumbraMessageHandler, this , size);
706+ if (!tp_pPumbra)
707+ rc = RCBAD; // not expected
708+ }
709+ else
710+ tp_PumbraClearIf ();
711+
712+ return rc;
713+ } // TOPRAT::tp_PumbraInit
714+ // -----------------------------------------------------------------------------
715+ void TOPRAT::tp_PumbraDestroy ()
716+ { delete tp_pPumbra;
717+ tp_pPumbra = NULL ;
718+ } // TOPRAT::tp_PumbraDestroy
719+ // -----------------------------------------------------------------------------
720+ int TOPRAT::tp_PumbraClearIf () // clear Penumbra data if any
721+ // returns 0 if Penumbra not instantiated, nothing done
722+ // 1 if data successfully cleared
723+ { if (!tp_pPumbra)
724+ return 0 ; // nothing to do
725+
726+ tp_pPumbra->clearModel ();
727+ return 1 ;
728+ } // TOPRAT::tp_PumbraClearIf
729+ // -----------------------------------------------------------------------------
730+ int TOPRAT::tp_PumbraAvailability () const
731+ {
732+ return tp_pPumbra != NULL ;
733+ } // TOPRAT::tp_PumbraAvailability
734+ // -----------------------------------------------------------------------------
735+ RC TOPRAT::tp_PumbraSetModel ()
736+ {
737+ RC rc = tp_pPumbra->setModel () == Pumbra::PN_SUCCESS
738+ ? RCOK
739+ : RCBAD;
740+ // message?
741+ return rc;
742+ } // TOPRAT::tp_PumbraSetModel
743+ // -----------------------------------------------------------------------------
744+ int TOPRAT::tp_ExshCount ()
745+ // returns nz if current project has ANY shading surface
746+ {
747+ int pvCount = 0 ;
748+ PVARRAY* pPV;
749+ RLUP ( PvR, pPV)
750+ { if (pPV->pv_HasPenumbraShading ())
751+ pvCount++;
752+ }
753+
754+ int sxCount = SxR.GetCount ();
755+
756+ tp_exshNShade = pvCount + sxCount; // # of shade surfaces
757+ tp_exshNRec = pvCount; // # of receiving surfaces
758+
759+ return pvCount > 1 || (pvCount > 0 && sxCount > 0 );
760+ } // TOPRAT::tp_ExshCount
761+ // -----------------------------------------------------------------------------
681762RC TOPRAT::tp_ExshRunInit () // start-of-run init for Penumbra shading
682763// sets up Penumbra model from all shading or receiving objects
683764{
684765 RC rc = RCOK;
685766
767+ #if defined( PUMBRAIF)
768+ if (!tp_ExshCount ())
769+ { tp_PumbraClearIf (); // clear Penumbra data if any
770+ return RCOK;
771+ }
772+
773+ // shading is required
774+ tp_PumbraInit ();
775+
776+ // building rotation
777+ // construct rotation matrix re C_SHADETY_BLDG
778+ CT3D MRot ( 1 ); // rotation matrix
779+ MRot.Rotate ( tp_bldgAzm, -2 ); // rotate about z axis
780+ // -2 = right-handed coord system
781+
782+ int NShade = 0 ; // # of shade surfaces
783+ int NRec = 0 ; // # of receiving surfaces
784+
785+ // create Penumbra surface model
786+ PVARRAY* pPV;
787+ RLUP ( PvR, pPV)
788+ rc |= pPV->pv_SetupShading ( NRec, &MRot);
789+
790+ SHADEX* pSX;
791+ RLUP ( SxR, pSX)
792+ rc |= pSX->sx_SetupShading ( NShade, &MRot);
793+
794+ if (!rc)
795+ rc = tp_PumbraSetModel ();
796+ #else
797+
686798 // route Penumbra messages to CSE output
687799 // use pumbra as context even though only one
688800 pumbra.setMessageCallback ( PemumbraMessageHandler, &pumbra);
@@ -712,7 +824,7 @@ RC TOPRAT::tp_ExshRunInit() // start-of-run init for Penumbra shading
712824 { if (pumbra.setModel () != Pumbra::PN_SUCCESS)
713825 rc |= RCBAD;
714826 }
715-
827+ # endif
716828 return rc;
717829
718830} // TOPRAT::tp_ExshRunInit
@@ -740,5 +852,6 @@ RC TOPRAT::tp_ExshBegHour() // once-per-hour exterior shading setup
740852} // TOPRAT::tp_ExshBegHour
741853
742854
855+
743856// shading.cpp end
744857
0 commit comments