aboutsummaryrefslogtreecommitdiff
path: root/vrayPlug/plugin/pluginMain.cpp
blob: f225ae3e05a24261ada2bb988839b2d8f73853ae (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
// Shave and a Haircut
// (c) 2019 Epic Games
// US Patent 6720962

#include "shaveVrayPlugin.h"
#include "shaveVrayDesc.h"
#include "shaveVraySharedFunctions.h"

extern "C"
{
#include "shaveSDKFUNCS2.h"
}

using namespace VR;

// defined in shaveVrayPlugin.cpp; set to true if SHAVE2init() has been called.
extern int shaveInitCalled;

struct shaveVrayParams: public VR::VRayParameterListDesc {
public:
	shaveVrayParams() {
		// Cannot initialise here because this struct is initialised
		// when the plugin is loaded before the check for V-Ray's
		// version runs and the addParamX methods of V-Ray 3 and 4
		// differ. This leads to a crash on MacOS. On other OSes the
		// dll simply doesn't load.
	}
	void init();
	virtual ~shaveVrayParams(){}
};


void shaveVrayParams::init()
{
	addParamInt	  (VR30_CONST_STR_HACK("stackId"),  0, -1);
	addParamInt	  (VR30_CONST_STR_HACK("instanced"),0, -1);
	addParamInt	  (VR30_CONST_STR_HACK("ownshader"),1, -1);
	addParamInt	  (VR30_CONST_STR_HACK("squirrel"),0, -1);
	addParamInt	  (VR30_CONST_STR_HACK("tipfade"),0, -1);
	addParamColor (VR30_CONST_STR_HACK("spectint"), VR::Color(1.0f,1.0f,1.0f), -1);
	addParamColor (VR30_CONST_STR_HACK("spectint2"),VR::Color(0.0f,0.0f,0.0f), -1);
	addParamString(VR30_CONST_STR_HACK("draFile"), "",-1);
	addParamString(VR30_CONST_STR_HACK("libPath"), "",-1);

	//uvs relaated params
	//DefVectorListParam is used for uvs list
	addParamInt(VR30_CONST_STR_HACK("numFacesPerInst"),0,-1);
	addParamInt(VR30_CONST_STR_HACK("numUVSets"),0,-1);
	//If -1, then this is not a list parameter; 
	//if 0 then this is a list parameter of unspecified (arbitrary) length. 
	//If this is >0, then it is the number of required elements in the parameter. 
	addParamVector(VR30_CONST_STR_HACK("uvs"),VR::Vector(),0);

	addParamInt(VR30_CONST_STR_HACK("draData"),0,0);
	addParamInt(VR30_CONST_STR_HACK("draSize"),0,-1);

	//visibility related params
	addParamInt(VR30_CONST_STR_HACK("cameraVisibility"),1, -1);
	addParamInt(VR30_CONST_STR_HACK("reflVisibility"),1, -1);
	addParamInt(VR30_CONST_STR_HACK("refrVisibility"),1, -1);
	addParamInt(VR30_CONST_STR_HACK("lightVisibility"),1, -1);
	addParamInt(VR30_CONST_STR_HACK("GiVisibility"),1, -1);

	addParamFloat(VR30_CONST_STR_HACK("selfShadow"),1.0f, -1);
	addParamInt(VR30_CONST_STR_HACK("recvShadow"),1, -1);
#if defined(VRAY30) || defined(VRAY40)
	addParamInt(VR30_CONST_STR_HACK("useGlobalHairTree"),1 /*1*/, -1);
	addParamInt(VR30_CONST_STR_HACK("dynamicHairTesselation"),0, -1);
	addParamFloat(VR30_CONST_STR_HACK("hairTesselMaxEdgleLen"),4.0f, -1);
#endif
}

#if defined(VRAY40)
#  define BUILT_FOR "4.0"
#elif defined(VRAY30)
#  if VRAY_DLL_VERSION < 0x31000
#    define BUILT_FOR "3.0"
#  elif VRAY_DLL_VERSION < 0x36000
#    define BUILT_FOR "3.1"
#  else
#    define BUILT_FOR "3.6"
#  endif
#else
#    define BUILT_FOR "2.0"
#endif

// We don't use the PLUGIN_DESC macro as we need to call the Shave cleanup function
// when the plugin is unloaded.
class shaveVrayPluginDesc: public VRayPluginDesc {
	int attachCount;
	VUtils::FastCriticalSection attachCsect;
public:
	shaveVrayParams shaveVrayPlugin_params;
	shaveVrayPluginDesc(void):VRayPluginDesc(NULL), attachCount(0) {
		parameters=&shaveVrayPlugin_params;
		(*getNumDescs())++;
		DescList *nd=new DescList;
		nd->desc=this;
		nd->next=(*getFirstDesc());
		(*getFirstDesc())=nd;

		unsigned int vr_rev = VR::getVRayRevision();

		unsigned int vr_rev_max;
		unsigned int vr_rev_min;
#if defined(VRAY40)
		vr_rev_min = 0x40000;
		vr_rev_max = 0x50000;
#elif defined(VRAY30)
#  if VRAY_DLL_VERSION < 0x31000
		vr_rev_min = 0x30000;
		vr_rev_max = 0x31000;
#  elif VRAY_DLL_VERSION < 0x36000
		vr_rev_min = 0x31000;
		vr_rev_max = 0x36000;
#  else
		vr_rev_min = 0x31000;
		vr_rev_max = 0x40000;
#  endif
#else
		vr_rev_min = 0;
		vr_rev_max = 0x30000;
#endif
		if (vr_rev < vr_rev_min || vr_rev >= vr_rev_max) {
			(*getNumDescs())=0;
			(*getFirstDesc())=NULL;
			printf("Skipping shave shaders for V-Ray " BUILT_FOR ".\n");fflush(stdout);
		} else {
			shaveVrayPlugin_params.init();
			printf("Loaded shave shaders for V-Ray " BUILT_FOR ".\n");fflush(stdout);
		}
	}
	PluginID getPluginID(void) { return shaveVrayPluginID; }
	Plugin* newPlugin(PluginHost *host) { return new shaveVrayPlugin(this); }
	void deletePlugin(Plugin *obj) { delete (shaveVrayPlugin*) obj; }
	bool supportsInterface(InterfaceID id) { return (id==EXT_STATIC_GEOM_SOURCE) || (id==EXT_VRAY_PLUGIN); }
#ifdef VRAY40
	const tchar *getName(void) { return shaveVrayPluginName; }
	const tchar *getDescription() const { return "Shave and a Haircut support for V-Ray"; }
#else
	tchar *getName(void) { return const_cast<tchar*>(shaveVrayPluginName); }
#endif
	const tchar *getCopyright(void) { return "(c) 2019 Epic Games"; }

	void attachToHost(PluginHost *host) {
		VUtils::FastCriticalSectionRAII lock(attachCsect);
		attachCount++;
	}

	void detachFromHost(PluginHost *host) {
		VRayPluginDesc::detachFromHost(host);

		VUtils::FastCriticalSectionRAII lock(attachCsect);
		attachCount--;
		// Call Shave cleanup, but only if it has been initialized for some render before.
		if (shaveInitCalled && attachCount==0) {
			SHAVE2cleanup();
			shaveInitCalled=false;
		}
	}
};

static shaveVrayPluginDesc desc_shaveVrayPlugin;

// PLUGIN_DESC(shaveVrayPluginID, EXT_STATIC_GEOM_SOURCE, shaveVrayPluginName, shaveVrayPlugin, shaveVrayParams);

PLUGIN_LIBRARY(VR30_CONST_STR_HACK("shavePlugins"), VR30_CONST_STR_HACK("shaveVrayShader plug-in."));

#ifdef WIN32
#ifdef _MANAGED
#pragma managed(push, off)
#endif

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
					 )
{
	hInstance = hModule;
 
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
		{
#if 0 // this is handled in the PluginDesc constructor now
			unsigned int vr_rev = VR::getVRayRevision();
			//printf("vray version 0x%x \n", vr_rev);fflush(stdout);
#ifdef VRAY30
			if(vr_rev < 0x30000) 
			{
				//its not a cracefull exit becuse fires dll loading error
				//need better solution.
				//return FALSE;

				//3.0 does not fire error, while 2.0 does
				//gr, 3.0 does as well
				(*getNumDescs())=0;
				(*getFirstDesc())=NULL;
				printf("Skipping shave shaders for Vray 3.0.\n");fflush(stdout);
			} else
				printf("Shave shaders for Vray 3.0 loaded.\n");fflush(stdout);
#else
			if(vr_rev >= 0x30000) 
			{
				//its not a cracefull exit becuse fires dll loading error
				//need better solution.
				//return FALSE;

				(*getNumDescs())=0;
				(*getFirstDesc())=NULL;
				printf("Skipping shave shaders for Vray 2.0.\n");fflush(stdout);
			} else
				printf("Shave shaders for Vray 2.0 loaded.\n");fflush(stdout);
#endif
#endif
			char* temp = getenv("TEMP");
			char  path[MAX_PATH];
#ifdef DO_LOGS
			sprintf(path,"%s/vray_Shave.log",temp);
			alog = fopen(path,"w");
			LOGMSG("DLL", "shaveVrayShader DLL loaded.")
#endif
			// Don't init Shave here; do that on demand in the shaveVrayPlugin::renderBegin().
			// In this way Shave is not initialized at all if it is not used in the scene.
			// SHAVE2init();
		}
		break;
	case DLL_THREAD_ATTACH:
	case DLL_THREAD_DETACH:
		break;
	case DLL_PROCESS_DETACH:
		{
			// Do not cleanup Shave here; do that in the hostDetach() method of the plugin
			// descriptor. This is because SHAVE2cleanup() cleans up some threads and it waits for them
			// to complete, however calls to DllMain() are serialized and SHAVE2cleanup() may
			// hang indefinitely as some threads attempt to call DllMain() for DLL_THREAD_DETACH.
			// SHAVE2cleanup();
			printf("Shave shaders for Vray unloaded.\n");fflush(stdout);
#ifdef DO_LOGS
			if(alog)
			{
				LOGMSG("DLL", "shaveVrayShader DLL unloaded.")
				fclose(alog);
				alog = NULL;
			}
#endif
		}
		break;
	}
    return TRUE;
}


#ifdef _MANAGED
#pragma managed(pop)
#endif
#endif