Example #1
0
//-------------------------------------------------------------------------------
//
// DoContinue
//
// If we get here we probably did something wrong. This selector was needed
// before advanceState() was in the FilterRecord*. Now that we use advanceState()
// there is nothing for us to do but set all the rectangles to 0 and return.
//
//-------------------------------------------------------------------------------
void DoContinue(void)
{
	VRect zeroRect = { 0, 0, 0, 0 };

	SetInRect(zeroRect);
	SetOutRect(zeroRect);
	SetMaskRect(zeroRect);
}
Example #2
0
static int16 RunPlugin(const int16 iSelector)
{
	string sError;
	try
	{
		if(gFilterRecord->bigDocumentData != NULL)
			gFilterRecord->bigDocumentData->PluginUsing32BitCoordinates = true;

		switch(iSelector)
		{
		case filterSelectorParameters:	break;
		case filterSelectorPrepare:	break;
		case filterSelectorStart:
		{
			Run();
			printf("UI shutdown\n");
			break;
		}
		case filterSelectorContinue:
		{
			VRect zeroRect = { 0, 0, 0, 0 };

			SetInRect(gFilterRecord, zeroRect);
			SetOutRect(gFilterRecord, zeroRect);
			SetMaskRect(gFilterRecord, zeroRect);
			break;
		}
		case filterSelectorFinish:
			break;
		}
	} catch(const std::bad_alloc &) {
		return memFullErr;
	} catch(const PhotoshopErrorException &e) {
		return e.m_iErr;
	} catch(const exception &e) {
		/* Don't let any exceptions propagate back into Photoshop. */
		sError = e.what();
	} catch(...) {
		sError = "Unknown exception";
	}

	if(sError.empty())
		return noErr;

	PlatformData *pPlatform = (PlatformData *) gFilterRecord->platformData;
	HWND hWnd = (HWND) pPlatform->hwnd;
	MessageBox(hWnd, sError.c_str(), plugInName, MB_OK);

	/* Is it OK to return userCanceledErr for a non-cancellation error?  The only
	 * difference seems to be that this doesn't display a "couldn't be completed because
	 * of a program error" dialog, which is what we want since we already displayed
	 * the error. */
	return userCanceledErr;
}
Example #3
0
void DoContinue(void)
{
	VRect outRect = { 0, 0, 0, 0};
	SetOutRect(outRect);
}
Example #4
0
void DoStart(void)
{
	// initialize the scene
	PI3DScene *theScene=PI3DCreateScene(NULL);
			
	char			currentMaterial[MAX_LINE];
	PI3DMesh			*mesh;
	PI3DMaterial		*material;
	int32			currentMaterialID;

	//create the default material - required
	strncpy(currentMaterial, "__PS_CS3_3D_Default", MAX_LINE-1);
	currentMaterial[MAX_LINE-1] = '\0';
	currentMaterialID = 0;
	material = PI3DUpdateMaterials(theScene, currentMaterial, 0);
	material->diffuse.red = 1.0;
	material->diffuse.green = 1.0;
	material->diffuse.blue = 1.0;
	
	//Create a second material with the 2 maps attached
	strncpy(currentMaterial, "MyMaterial", MAX_LINE-1);
	currentMaterial[MAX_LINE-1] = '\0';
	currentMaterialID = 1;
	material = PI3DUpdateMaterials(theScene, currentMaterial, 0);
	material->diffuse.red = 0.8;
	material->diffuse.green = 0.8;
	material->diffuse.blue = 0.8;
	material->ambient.red = 0.8;
	material->ambient.green = 0.8;
	material->ambient.blue = 0.8;
	material->specular.red = 0.6;
	material->specular.green = 0.6;
	material->specular.blue = 0.6;
	strncpy(material->maps[PI3DDiffuseMap].map, "Diffuse.png", 2047);
	material->maps[PI3DDiffuseMap].map[2047] = '\0';
	material->maps[PI3DDiffuseMap].strength=1.0f;
	material->maps[PI3DDiffuseMap].flags=(PI3DTextureMapFlags)0;
	
	strncpy(material->maps[PI3DBumpMap].map, "Bump.png", 2047);
	material->maps[PI3DBumpMap].map[2047] = '\0';
	material->maps[PI3DBumpMap].strength=1.0f;
	material->maps[PI3DBumpMap].flags=(PI3DTextureMapFlags)0;
	
	//Create an empty mesh and add to list
	mesh = PI3DCreateMesh((char*)"", 0, 0, 0, 0, 0, 0);
	PI3DListAdd((PI3DList **)&theScene->meshList, reinterpret_cast<PI3DList *>(mesh));
	
	//Get things ready to cycle through the pixels
	int16 tileHeight = gFilterRecord->outTileHeight;
	int16 tileWidth = gFilterRecord->outTileWidth;

	if (tileWidth == 0 || tileHeight == 0 || gFilterRecord->advanceState == NULL)
	{
		*gResult = filterBadParameters;
		return;
	}
	
	VRect outRect = GetOutRect();
	VRect filterRect = GetFilterRect();
	
	int32 imageVert = filterRect.bottom - filterRect.top;
	int32 imageHor = filterRect.right - filterRect.left;

	uint32 tilesVert = (tileHeight - 1 + imageVert) / tileHeight;
	uint32 tilesHoriz = (tileWidth - 1 + imageHor) / tileWidth;

	int16 layerPlanes = 1;
	if (gFilterRecord->filterCase > 2)
		layerPlanes = gFilterRecord->outLayerPlanes;
	else
		layerPlanes = gFilterRecord->planes;

	
	int32 progress_total = layerPlanes * tilesVert;
	int32 progress_complete = 0;
	
	//Allocate the space for the vertices and uvs of the mesh
	mesh->vertices=imageVert*imageHor;
	mesh->vertex = (PI3DVector *)PI3DMemoryAlloc(sizeof(PI3DVector) * mesh->vertices);
	mesh->textures=imageVert*imageHor;
	mesh->texture = (PI3DPoint *)PI3DMemoryAlloc(sizeof(PI3DPoint) * mesh->textures);
	mesh->faces=(imageVert-1)*(imageHor-1);
	mesh->face = (PI3DFace *)PI3DMemoryAlloc(sizeof(PI3DFace) * mesh->faces);
	mesh->smoothingGroupPresent = true;
	
	//We'll just grab the red channel for now
	int16 planeCount = 0;
	//for(int16 planeCount = 0; planeCount < layerPlanes; planeCount++)
	{
		gFilterRecord->outLoPlane = planeCount;
		gFilterRecord->outHiPlane = planeCount;

		for(uint16 vertTile = 0; vertTile < tilesVert; vertTile++)
		{
			for(uint16 horizTile = 0; horizTile < tilesHoriz; horizTile++)
			{
				outRect.top = filterRect.top + ( vertTile * tileHeight );
				outRect.left = filterRect.left + ( horizTile * tileWidth );
				outRect.bottom = outRect.top + tileHeight;
				outRect.right = outRect.left + tileWidth;

				if (outRect.bottom > filterRect.bottom)
					outRect.bottom = filterRect.bottom;
				if (outRect.right > filterRect.right)
					outRect.right = filterRect.right;

				SetOutRect(outRect);

				*gResult = gFilterRecord->advanceState();
				if (*gResult != kNoErr) return;

				outRect = GetOutRect();
				
				uint8 * smallPixel = static_cast<uint8 *>(gFilterRecord->outData);
				uint16 * largePixel = static_cast<uint16 *>(gFilterRecord->outData);

				uint32 rectHeight = outRect.bottom - outRect.top;
				uint32 rectWidth = outRect.right - outRect.left;

				for(uint32 pixelY = 0; pixelY < rectHeight; pixelY++)
				{
					for(uint32 pixelX = 0; pixelX < rectWidth; pixelX++)
					{
						uint32 x	=	outRect.left	+	pixelX;
						uint32 y	=	outRect.top		+	pixelY;
						
						uint32 vertexIndex = x + imageHor*y;
						uint16 height=0;
						
						if (gFilterRecord->depth == 8 && *smallPixel)
							height=*smallPixel;
						if (gFilterRecord->depth == 16 && *largePixel)
							height=*largePixel;
						
						//Calculate each vertex based on the pixel value
						mesh->vertex[vertexIndex][0]=imageHor-x;
						mesh->vertex[vertexIndex][1]=height;
						mesh->vertex[vertexIndex][2]=imageVert-y;
						
						//Calculate each texture coordinate based on the pixel value
						mesh->texture[vertexIndex][0]=((nativeFloat)x)/((nativeFloat)imageHor);
						mesh->texture[vertexIndex][1]=((nativeFloat)(imageVert-y))/((nativeFloat)imageVert);
									
						largePixel++;
						smallPixel++;
					}
					smallPixel += gFilterRecord->outRowBytes - rectWidth;
					largePixel += gFilterRecord->outRowBytes / 2 - rectWidth;
				}

			}

			gFilterRecord->progressProc(++progress_complete, progress_total);

			if (gFilterRecord->abortProc()) 
			{
				*gResult = userCanceledErr;
				goto done;
			}
		}
	}
done:
	
	outRect.top = 0;
	outRect.left = 0;
	outRect.bottom = 0;
	outRect.right = 0;
	SetOutRect(outRect);
	
	//Cycle back through and create faces to map to the vertices and uvs we made
	int32 x1,y1,faceIndex=0;
	for(y1=filterRect.top; y1<filterRect.bottom-1;y1++)
		{
		
		int32 topLeft=y1*imageHor;
		int32 topRight=1+y1*imageHor;
		int32 bottomLeft=(y1+1)*imageHor;
		int32 bottomRight=1+(y1+1)*imageHor;
		
		for(x1=filterRect.left; x1<filterRect.right-1;x1++)
			{
			//Only add a face if there is a non-black value in one of the 4 corners - this is how holes are made
			if(mesh->vertex[topLeft][1] || mesh->vertex[topRight][1] || mesh->vertex[bottomLeft][1] || mesh->vertex[bottomRight][1])
				{
				int32		nPoints = 4;
				PI3DFace	f;
				memset(&f, 0, sizeof(f));
				f.points = (int32 *)PI3DMemoryAlloc(sizeof(int32) * nPoints);
				f.normals = (int32 *)PI3DMemoryAlloc(sizeof(int32) * nPoints);
				f.textures = (int32 *)PI3DMemoryAlloc(sizeof(int32) * nPoints);
				f.colors = (int32 *)PI3DMemoryAlloc(sizeof(int32) * nPoints);
				f.flags = 0x57;
				
				if (f.points == NULL || f.normals == NULL || f.textures == NULL || f.colors == NULL)
					break;
				f.smoothing = 1;
				f.material = currentMaterialID;
				f.numPoints = nPoints;
				
				f.points[0]=topLeft;
				f.normals[0]=topLeft;
				f.textures[0]=topLeft;
				f.colors[0]=topLeft;
				
				f.points[1]=topRight;
				f.normals[1]=topRight;
				f.textures[1]=topRight;
				f.colors[1]=topRight;
				
				f.points[2]=bottomRight;
				f.normals[2]=bottomRight;
				f.textures[2]=bottomRight;
				f.colors[2]=bottomRight;
				
				f.points[3]=bottomLeft;
				f.normals[3]=bottomLeft;
				f.textures[3]=bottomLeft;
				f.colors[3]=bottomLeft;
				
				mesh->face[faceIndex++]=f;
				}
			topLeft++;
			bottomRight++;
			bottomLeft++;
			topRight++;
			
			}
		}
	
	//Reset the # of faces to match how many we actually added
	mesh->faces=faceIndex;
			
	if(theScene)
		{
		//Fill in scene
		
		PI3DDescriptorProcs descriptorProcs;
		
		descriptorProcs.actionDescriptorProcs=NULL;
		descriptorProcs.actionListProcs=NULL;
		descriptorProcs.actionControlProcs=NULL;
		descriptorProcs.zStringProcs=NULL;
		
		int32 error = gFilterRecord->sSPBasic->AcquireSuite(kPSActionDescriptorSuite,
                                  kPSActionDescriptorSuiteVersion, 
                                  (const void**)&descriptorProcs.actionDescriptorProcs);    
		if(!error)
			error = gFilterRecord->sSPBasic->AcquireSuite(kPSActionListSuite,
                                  kPSActionListSuiteVersion,
                                  (const void**)&descriptorProcs.actionListProcs);
		if(!error)
			error = gFilterRecord->sSPBasic->AcquireSuite(kPSBasicActionControlSuite,
                                  kPSBasicActionControlSuitePrevVersion,
                                  (const void**)&descriptorProcs.actionControlProcs);
		if(!error)
			error = gFilterRecord->sSPBasic->AcquireSuite(kASZStringSuite,
                                  kASZStringSuiteVersion1, 
                                  (const void**)&descriptorProcs.zStringProcs);

		PIActionDescriptor theLayerDescriptor=NULL;
		if(!error)
			{
			
			descriptorProcs.actionDescriptorProcs->Make(&theLayerDescriptor);
			if(theLayerDescriptor)
				{
				PI3DLayer * theLayer = new PI3DLayer;
				if (theLayer == NULL) return;
				VPoint docSize;
				docSize.h=gFilterRecord->imageSize.h;
				docSize.v=gFilterRecord->imageSize.v;
				
				//Get the 3D layer set up
				PI3DInitialize3DLayer(theLayer,&docSize);
				
				//Hand it the scene we created
				theLayer->currentScene=theScene;
				
				//Fill in current camera and object position and the textures
				//Set up an orthographic camera to fit the object exactly in the view
				
				//This first section is for the View menu in the 3D tool
				theLayer->stateList.length=1;
				theLayer->stateList.positionNames=(uint16**)PI3DMemoryAlloc(theLayer->stateList.length * sizeof(uint16*)); 
				theLayer->stateList.positionNames[0] = (uint16*)PI3DMemoryAlloc(256 * sizeof(uint16));
				PI3DStringCopyC16(theLayer->stateList.positionNames[0],(const char *)"Test Camera");
				theLayer->stateList.viewStates=(RenderState*)PI3DMemoryAlloc(theLayer->stateList.length * sizeof(RenderState)); 
				memset(&theLayer->stateList.viewStates[0],0,sizeof(RenderState));
				
				if(gFilterRecord->depth == 8)
					theLayer->stateList.viewStates[0].currentCameraPosition.y = 400;
				else
					theLayer->stateList.viewStates[0].currentCameraPosition.y = 100000;
				theLayer->stateList.viewStates[0].currentOrthoScale=imageVert;
				theLayer->stateList.viewStates[0].currentOrthographic=true;
				theLayer->stateList.viewStates[0].currentCameraPosition.xAngle=-90;
				theLayer->stateList.viewStates[0].currentFieldOfView=42.0;
				theLayer->stateIndex=8;
				
				//This sets the current view to be this camera
				theLayer->currentRenderState.currentOrthoScale=theLayer->stateList.viewStates[0].currentOrthoScale;
				theLayer->currentRenderState.currentOrthographic=theLayer->stateList.viewStates[0].currentOrthographic;
				theLayer->currentRenderState.currentCameraPosition=theLayer->stateList.viewStates[0].currentCameraPosition;
				theLayer->currentRenderState.currentFieldOfView=theLayer->stateList.viewStates[0].currentFieldOfView;
				
				//Add in some textures
				theLayer->texturesExternal=true; //Textures are external to the file
				theLayer->texturesEnabled=true; //The master eyeball
				theLayer->textureList.length=2;
				
				//The individual eyyeballs
				theLayer->textureEnabled = (Boolean*)PI3DMemoryAlloc(theLayer->textureList.length * sizeof(Boolean));
				theLayer->textureEnabled[0]=true;
				theLayer->textureEnabled[1]=true;
				
				//The type of each texture - Note that bump maps disable the Cross Section tool
				theLayer->textureList.textureType = (uint32*)PI3DMemoryAlloc(theLayer->textureList.length * sizeof(uint32));
				theLayer->textureList.textureType[0]=k3DMapTypeTexture;
				theLayer->textureList.textureType[1]=k3DMapTypeBump;
				
				//We need to set a path for the scene so that PS knows where to look for textures
				theLayer->scenePath = (uint16*)PI3DMemoryAlloc(256 * sizeof(uint16));
				GetTempFolderPath( theLayer->scenePath, 256 * sizeof(uint16) - 1);
				StringAppend3D(theLayer->scenePath,(char*)"dummy.obj", 256 * sizeof(uint16));
				
				//Give the paths to the textures
				//In this case we're just going to give paths to nothing
				//This will create empty textures that users can fill in later
				//Note that whatever path you put in for texturePaths, that file will get removed as
				//it is assumed to be a temp file.  So, you probably want point it at a bogus file.
				theLayer->textureList.textureNames = (uint16**)PI3DMemoryAlloc(theLayer->textureList.length * sizeof(uint16*));
				theLayer->textureList.texturePaths =(uint16**) PI3DMemoryAlloc(theLayer->textureList.length * sizeof(uint16*));
				
				theLayer->textureList.texturePaths[0] = (uint16*)PI3DMemoryAlloc(256 * sizeof(uint16));
				theLayer->textureList.textureNames[0] = (uint16*)PI3DMemoryAlloc(256 * sizeof(uint16));
				theLayer->textureList.texturePaths[0][0]=0;
				GetTempFolderPath( theLayer->textureList.textureNames[0], 256 * sizeof(uint16) - 1);
				StringAppend3D(theLayer->textureList.textureNames[0],(char*)"Diffuse.png", 256 * sizeof(uint16));
				StringAppend3D(theLayer->textureList.texturePaths[0],(char*)"Diffuse.png", 256 * sizeof(uint16));
				
				theLayer->textureList.texturePaths[1] = (uint16*)PI3DMemoryAlloc(256 * sizeof(uint16));
				theLayer->textureList.textureNames[1] = (uint16*)PI3DMemoryAlloc(256 * sizeof(uint16));
				theLayer->textureList.texturePaths[1][0]=0;
				GetTempFolderPath( theLayer->textureList.textureNames[1], 256 * sizeof(uint16) - 1);
				StringAppend3D(theLayer->textureList.texturePaths[1],(char*)"Bump.png", 256 * sizeof(uint16));
				StringAppend3D(theLayer->textureList.textureNames[1],(char*)"Bump.png", 256 * sizeof(uint16));
				
				//Convert the entire layer data structure into a descriptor for Photoshop
				PI3DMakeLayerDescriptor(&descriptorProcs, theLayer, theLayerDescriptor);
				
				//Clean up behind us
				theLayer->currentScene=NULL;
				PI3DKill3DLayer(theLayer);
				delete theLayer;
				}
			}
			
		//Clean up behind us	
		if(theScene)
			PI3DKillScene(theScene);
		
		//Convert theLayerDescriptor to a handle and free the descriptor
		//When PS sees this descriptor handle it creates a new 3D layer with that data in it
		if(theLayerDescriptor)
			{
			descriptorProcs.actionDescriptorProcs->AsHandle(theLayerDescriptor, &gFilterRecord->output3DScene->descriptor);
			descriptorProcs.actionDescriptorProcs->Free(theLayerDescriptor);
			}
		
		}
}
Example #5
0
//-------------------------------------------------------------------------------
//
// DoFilter
//
// Randomly change the pixel values based on the parameters the user gave us from
// our dialog box or scripting. We do this a tile at a time making sure the rect.
// we ask for is in the bounds of the filterRect.
//
//-------------------------------------------------------------------------------
void DoFilter(void)
{
	// make the random number generated trully random
	srand((unsigned)time(NULL));

	int32 tileHeight = gFilterRecord->outTileHeight;
	int32 tileWidth = gFilterRecord->outTileWidth;

	if (tileWidth == 0 || tileHeight == 0)
	{
		*gResult = filterBadParameters;
		return;
	}

	VRect filterRect = GetFilterRect();
	int32 rectWidth = filterRect.right - filterRect.left;
	int32 rectHeight = filterRect.bottom - filterRect.top;

	CreateDissolveBuffer(tileWidth, tileHeight);

	// round up to the nearest horizontal and vertical tile count
	int32 tilesVert = (tileHeight - 1 + rectHeight) / tileHeight;
	int32 tilesHoriz = (tileWidth - 1 + rectWidth) / tileWidth;

	// Fixed numbers are 16.16 values 
	// the first 16 bits represent the whole number
	// the last 16 bits represent the fraction
	gFilterRecord->inputRate = (int32)1 << 16;
	gFilterRecord->maskRate = (int32)1 << 16;
 
	// variables for the progress bar, our plug in is so fast
	// we probably don't need these
	int32 progressTotal = tilesVert * tilesHoriz;
	int32 progressDone = 0;

	// loop through each tile makeing sure we don't go over the bounds
	// of the rectHeight or rectWidth
	for (int32 vertTile = 0; vertTile < tilesVert; vertTile++)
	{
		for (int32 horizTile = 0; horizTile < tilesHoriz; horizTile++)
		{
			UpdateDissolveBuffer(tileWidth, tileHeight);

			VRect filterRect = GetFilterRect();
			VRect inRect = GetInRect();

			inRect.top = vertTile * tileHeight + filterRect.top;
			inRect.left = horizTile * tileWidth + filterRect.left;
			inRect.bottom = inRect.top + tileHeight;
			inRect.right = inRect.left + tileWidth;

			if (inRect.bottom > rectHeight)
				inRect.bottom = rectHeight;
			if (inRect.right > rectWidth)
				inRect.right = rectWidth;

			SetInRect(inRect);

			// duplicate what's in the inData with the outData
			SetOutRect(inRect);
			
			// get the maskRect if the user has given us a selection
			if (gFilterRecord->haveMask)
			{
				SetMaskRect(inRect);
			}

			for (int16 plane = 0; plane < gFilterRecord->planes; plane++)
			{
				// we want one plane at a time, small memory foot print is good
				gFilterRecord->outLoPlane = gFilterRecord->inLoPlane = plane;
				gFilterRecord->outHiPlane = gFilterRecord->inHiPlane = plane;
	
				// update the gFilterRecord with our latest request
				*gResult = gFilterRecord->advanceState();
				if (*gResult != noErr) return;

				// muck with the pixels in the outData buffer
				uint8 color = 255;
				int16 expectedPlanes = CSPlanesFromMode(gFilterRecord->imageMode,
					                                    0);

				if (plane < expectedPlanes)
					color = gData->color[plane];

				DissolveRectangle(gFilterRecord->outData,
								  gFilterRecord->outRowBytes,
								  gFilterRecord->maskData,
								  gFilterRecord->maskRowBytes,
								  GetOutRect(), 
								  color,
								  gFilterRecord->depth);
			}

			// uh, update the progress bar
			gFilterRecord->progressProc(++progressDone, progressTotal);
			
			// see if the user is impatient or didn't mean to do that
			if (gFilterRecord->abortProc())
			{
				*gResult = userCanceledErr;
				return;
			}
		}
	}
	DeleteDissolveBuffer();
}