Skip to content

Commit a05a455

Browse files
committed
CSE 0.827
Penumbra instantiated iff needed Reduced OpenGL requirements Better Penumbra error messages
1 parent 84a7e84 commit a05a455

File tree

13 files changed

+804
-650
lines changed

13 files changed

+804
-650
lines changed

src/CGWTHR.CPP

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ RC TOPRAT::tp_WfInit() // Initialize weather file. Displays any error message
6666
// also uses: Top.tp_wfName [,.isDT]
6767
// returns non-RCOK if error, message already issued.
6868
{
69-
RC rc = Wfile.wf_Open( tp_wfName, tp_TDVfName, WRN); // open wthr file and option TDV file
70-
// init WFILE object msg if error.
69+
RC rc = Wfile.wf_Open( tp_wfName, tp_TDVfName); // open wthr file and option TDV file
70+
// init WFILE object, msg if error.
7171
if (!rc)
7272
rc = Wfile.wf_FillWDYEAR( WRN);
7373
return rc;

src/CNCULT2.CPP

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@ RC TOPRAT::tp_Wfile( // find/check weather file / init top members with data fr
469469
ppFindFile( tp_TDVfName); // auxiliary TDV (time dependent value) file if any
470470

471471
// open weather file
472-
RC rc = Wfile.wf_Open( tp_wfName, tp_TDVfName, WRN); // reports err if can't open.
472+
RC rc = Wfile.wf_Open( tp_wfName, tp_TDVfName); // reports err if can't open.
473473
if (!rc) // if opened ok
474474
{
475475
// fetch latitude, longitude, time zone to Top members
@@ -767,6 +767,9 @@ void TOPRAT::freeDM() // free child objects in DM
767767
#endif
768768
delete tp_pAirNet;
769769
tp_pAirNet = NULL;
770+
771+
tp_PumbraDestroy(); // cleanup / delete Penumbra shading machinery
772+
770773
//CHP monStr does not point into dm.
771774
} // TOPRAT::freeDM
772775
//---------------------------------------------------------------------------

src/CNGLOB.H

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,7 @@ typedef void* DMP; // Dynamic memory block pointer: ptr to any type, record stru
470470
inline void IncP( void **pp, int b) { *pp = (void *)((char*)(*pp) + b); }
471471
typedef USI PSOP; // type for pseudo-code opcodes -- used in sevaral .cpp files and in cuparse.h
472472
struct RXPORTINFO;
473+
namespace Pumbra { class Penumbra; }
473474

474475
#ifdef WINorDLL
475476
// control of scattered code for returning file names used via a cne() argument.

src/CNRECS.DEF

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,7 @@ RECORD TOPRAT "top" *RAT /* top level RAT: contains control info and all once-on
298298
//TOP: setup: exterior (non-overhang/fin) shading
299299
*r INT tp_exshNShade; // # of shading surfaces in model
300300
*r INT tp_exshNRec; // # of receiving surfaces in model (may also be shading)
301+
*declare "int tp_ExshCount();"
301302
*declare "RC tp_ExshRunInit();"
302303
*declare "RC tp_ExshBegHour();"
303304

@@ -569,6 +570,15 @@ x // not maintained, 12-12
569570
// TOP: runtime: AIRNET solution
570571
*declare "AIRNET* tp_pAirNet;"
571572

573+
// TOP: runtime: pointer to Penumbra (GPU shading) object
574+
// instantiated iff needed
575+
*declare "class Pumbra::Penumbra* tp_pPumbra;"
576+
*declare "RC tp_PumbraInit();"
577+
*declare "int tp_PumbraClearIf();"
578+
*declare "void tp_PumbraDestroy();"
579+
*declare "int tp_PumbraAvailability() const;"
580+
*declare "RC tp_PumbraSetModel();"
581+
572582
*r SI ck5aa5 // stuffed with 0x5aa5 from topCult for verifying initialization & matching versions
573583
*END // TOPRAT
574584

@@ -621,13 +631,13 @@ RECORD PY4 "4th power poly sub" *SUBSTRUCT // 4th power polynomial. for GT, whic
621631
RECORD WFILE "weatherFile" *RAT // weather file info, one static instance "Wfile", made a record 1-94 so probe-able
622632

623633
// CAUTION: record layout matches code in wfpak.cpp, do not change without updating header decode !!
624-
634+
*prefix wf_
625635
*excon // declare constructor WFILE( basAnc *b, TI i, SI noZ=0) in wfpak.cpp: calls init().
626636
*exdes // d'tor
627637
*ovrcopy // overridden Copy()
628638
*declare "WFILE();" // default c'tor
629639
*declare "void wf_Init();" // initialization member fcn
630-
*declare "RC wf_Open( const char* wfName, const char* TDVfName, int erOp=WRN, int wrA=FALSE, char* hdr=NULL,"
640+
*declare "RC wf_Open( const char* wfName, const char* TDVfName, int erOp=ERR, int wrA=FALSE, char* hdr=NULL,"
631641
*declare " float* clrnss=NULL, float* turbid=NULL, float* atmois=NULL);"
632642
*declare "RC wf_Close( char *hdr=NULL);"
633643
*declare "const char* wf_FilePath() const;"
@@ -660,7 +670,7 @@ RECORD WFILE "weatherFile" *RAT // weather file info, one static instance "Wfile
660670

661671
*declare "int wf_IsPacked() const { return wFileFormat==BSGS || wFileFormat==BSGSdemo || wFileFormat==ET1 || wFileFormat==ET2; }"
662672

663-
// Header info: from file hdr decode (wfpak:wfOpen) or computed from hourly
673+
// Header info: from file hdr decode or computed from hourly
664674
*r WFLOC loc // char loc[] Location (for ET, is loc 1 only: city etc).
665675
*r WFLID lid // char lid[] Location ID
666676
*r SI yr // Year of weather data (00 - 99, -1 if N/A)
@@ -696,8 +706,8 @@ RECORD WFILE "weatherFile" *RAT // weather file info, one static instance "Wfile
696706
// *array 12 *r float atmois // monthly aveage atmospheric moisture, for daylight calcs
697707

698708
// TDV file header info
699-
*r WFLOC wf_TDVFileTimeStamp // timestamp string
700-
*r WFLOC wf_TDVFileTitle // title string (identifies file CZ, fuel, vintage, )
709+
*f WFLOC wf_TDVFileTimeStamp // timestamp string
710+
*f WFLOC wf_TDVFileTitle // title string (identifies file CZ, fuel, vintage, )
701711

702712
//internal
703713
*r *hide SI hdrBytes // # header bytes before first record (used in wfread for file positioning)

src/MSGTBL.CPP

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1527,7 +1527,7 @@ x { MH_T0003, "\nReport file name: %s" },
15271527
{ MH_I0116, "I0116: Unrecognized character(s) after %snumber \"%s\"." },
15281528
{ MH_I0117, "I0117: Internal error: Invalid call to YACAM::get(): \n NULL not found at end arg list.\n" },
15291529
//errFlLn meta-message, no msg number in text:
1530-
{ MH_I0118, ": Error in %s %s near line %d:\n %s" },
1530+
{ MH_I0118, "%s '%s' (near line %d):\n %s" },
15311531

15321532
// nb: no terminator, use msgTblCount
15331533
};

src/PVCalc.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ RC PVARRAY::pv_CalcPOA()
401401
// Calculate plane-of-array incidence
402402
int sunupSrf; // nz iff
403403
float cosi, fBeam;
404-
if (pv_HasPenumbraShading())
404+
if (pv_HasPenumbraShading() && Top.tp_PumbraAvailability() > 0)
405405
sunupSrf = pv_CalcBeamShading( cosi, fBeam);
406406
else
407407
{ // tracking: Penumbra shading not supported

src/SHADING.CPP

Lines changed: 122 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,13 @@
3737

3838
#include <penumbra/penumbra.h>
3939

40+
#define PUMBRAIF
41+
#if defined PUMBRAIF
42+
#define PUMBRA( m) (Top.tp_pPumbra->m)
43+
#else
4044
static 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+
//-----------------------------------------------------------------------------
681762
RC 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


src/WFPAK.CPP

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,7 +1037,8 @@ RC WFILE::wf_Open( // Open existing weather file and initialize WFILE structure
10371037

10381038
const char* wfName, // file path
10391039
const char* TDVfName, // optional TDV file path, NULL = no TDV file
1040-
int erOp /*=WRN*/, // error handling: WRN, IGN etc
1040+
int erOp /*=ERR*/, // error handling: ERR, WRN, IGN etc
1041+
// default ERR: report error, return rc != RCOK
10411042
int wrAccess/*=FALSE*/, // write access desired. Used only in utilities (not in CSE).
10421043
char* hdr /*=NULL*/, // non-null to return raw header of packed files. For wthr utility programs.
10431044
// WFHDRSZ bytes returned even if file's hdr smaller.
@@ -1048,7 +1049,7 @@ RC WFILE::wf_Open( // Open existing weather file and initialize WFILE structure
10481049
float* turbid /*=NULL*/, // receives 12 monthly average atmospheric turbidity values
10491050
float* atmois /*=NULL*/ ) // receives 12 monthly average atmospheric moisure values
10501051

1051-
// returns RCOK if all ok,
1052+
// returns RCOK iff success
10521053
// else other value, message issued per erOp
10531054

10541055
// sets isLeap if leap year file (future ET1 files 10-94).
@@ -1095,7 +1096,7 @@ x xfFindOnPath issued msg per erOp.*/
10951096
RC rcTDV = wf_TDVOpen( TDVfName, erOp);
10961097
if (rcTDV)
10971098
{ err( erOp, // display msg per erOp, rmkerr.cpp
1098-
rc==RCBAD2
1099+
rcTDV==RCBAD2
10991100
? (char *)MH_R0101 // "R0101: %s file '%s': bad format or header"
11001101
: (char *)MH_R0100, // "R0100: %s file '%s': open failed"
11011102
"TDV", TDVfName);
@@ -1761,8 +1762,10 @@ RC WFILE::wf_TDVReadHdr( int erOp) // read / decode TDV file header
17611762

17621763
// initial tag
17631764
rc = yacTDV->getLineCSV( erOp, 0, "CC", _C( T1), _C( T2), NULL);
1764-
if (!strMatch( T1, "TDV Data (TDV/Btu)"))
1765-
rc = err( erOp, "Munged header");
1765+
const char* TDVFileTag = "TDV Data (TDV/Btu)";
1766+
if (!strMatch( T1, TDVFileTag))
1767+
rc = yacTDV->errFlLn( "Incorrect first item \"%s\" -- expected \"%s\"",
1768+
T1, TDVFileTag);
17661769
if (!rc)
17671770
// time stamp
17681771
rc = yacTDV->getLineCSV( erOp, 0, "C", _C( wf_TDVFileTimeStamp), NULL);
@@ -1773,8 +1776,8 @@ RC WFILE::wf_TDVReadHdr( int erOp) // read / decode TDV file header
17731776
// column heads (ignored)
17741777
rc = yacTDV->getLineCSV( erOp, 0, "CC", _C(T1), _C( T2), NULL);
17751778

1776-
if (!rc)
1777-
wf_TDVInitHdrInfo();
1779+
if (rc)
1780+
wf_TDVInitHdrInfo(); // error: clear any partial data
17781781

17791782
return rc;
17801783

0 commit comments

Comments
 (0)