Example #1
0
void PhotonEstimationTask::EstimatePhotonsForObjectAndLight(ObjectPtr Object, LightSource *Light)
{
	int mergedFlags=0;             /* merged flags to see if we should shoot photons */
	ViewThreadData *renderDataPtr = GetViewDataPtr();

	/* first, check on various flags... make sure all is a go for this ObjectPtr */
	LightTargetCombo combo(Light,Object);
	mergedFlags = combo.computeMergedFlags();

	if (!( ((mergedFlags & PH_RFR_ON_FLAG) && !(mergedFlags & PH_RFR_OFF_FLAG)) ||
	       ((mergedFlags & PH_RFL_ON_FLAG) && !(mergedFlags & PH_RFL_OFF_FLAG)) ))
		/* it is a no-go for this object... bail out now */
		return;

	if(!Object) return;

	ShootingDirection shootingDirection(Light,Object);
	shootingDirection.compute();

	/* calculate the spacial separation (spread) */
	renderDataPtr->photonSpread = combo.target->Ph_Density*GetSceneData()->photonSettings.surfaceSeparation;

	/* if rays aren't parallel, divide by dist so we get separation at a distance of 1 unit */
	if (!combo.light->Parallel)
	{
		renderDataPtr->photonSpread /= shootingDirection.dist;
	}

	/* try to guess the number of photons */
	DBL x=shootingDirection.rad / (combo.target->Ph_Density*GetSceneData()->photonSettings.surfaceSeparation);
	x=x*x*M_PI;

	if ( ((mergedFlags & PH_RFR_ON_FLAG) && !(mergedFlags & PH_RFR_OFF_FLAG)) &&
	     ((mergedFlags & PH_RFL_ON_FLAG) && !(mergedFlags & PH_RFL_OFF_FLAG)) )
	{
		x *= 1.5;  /* assume 2 times as many photons with both reflection & refraction */
	}

	if ( !Test_Flag(combo.target, PH_IGNORE_PHOTONS_FLAG) )
	{
		if ( ((mergedFlags & PH_RFR_ON_FLAG) && !(mergedFlags & PH_RFR_OFF_FLAG)) )
		{
			if ( ((mergedFlags & PH_RFL_ON_FLAG) && !(mergedFlags & PH_RFL_OFF_FLAG)) )
				x *= 3;  /* assume 3 times as many photons if ignore_photons not used */
			else
				x *= 2;  /* assume less for only refraction */
		}
	}

	x *= 0.5;  /* assume 1/2 of photons hit target ObjectPtr */

	photonCountEstimate += x;
}
Example #2
0
void PhotonSortingTask::SendProgress(void)
{
#if 0
    // TODO FIXME PHOTONS
    // for now, we won't send this, as it can be confusing on the front-end due to out-of-order delivery from multiple threads.
    // we need to create a new progress message for sorting.
    if (timer.ElapsedRealTime() > 1000)
    {
        timer.Reset();
        POVMS_Object obj(kPOVObjectClass_PhotonProgress);
        obj.SetInt(kPOVAttrib_CurrentPhotonCount, (GetSceneData()->surfacePhotonMap.numPhotons + GetSceneData()->mediaPhotonMap.numPhotons));
        RenderBackend::SendViewOutput(GetViewData()->GetViewId(), GetSceneData()->frontendAddress, kPOVMsgIdent_Progress, obj);
    }
#endif
}
Example #3
0
void PhotonEstimationTask::SearchThroughObjectsEstimatePhotons(vector<ObjectPtr>& Objects, LightSource *Light)
{
	ViewThreadData *renderDataPtr = GetViewDataPtr();
	shared_ptr<SceneData> sceneData = GetSceneData();

	/* check this object and all siblings */
	for(vector<ObjectPtr>::iterator Sib = Objects.begin(); Sib != Objects.end(); Sib++)
	{
		if(Test_Flag((*Sib), PH_TARGET_FLAG) &&
		    !((*Sib)->Type & LIGHT_SOURCE_OBJECT))
		{
			/* do not shoot photons if global lights are turned off for ObjectPtr */
			if(!Test_Flag((*Sib), NO_GLOBAL_LIGHTS_FLAG))
			{
				EstimatePhotonsForObjectAndLight((*Sib), Light);
			}

			Cooperate();
		}
		/* if it has children, check them too */
		else if(((*Sib)->Type & IS_COMPOUND_OBJECT))
		{
			SearchThroughObjectsEstimatePhotons(((CSG *)(*Sib))->children, Light);
		}
	}
}
Example #4
0
void PhotonSortingTask::Run()
{
    // quit right away if photons not enabled
    if (!GetSceneData()->photonSettings.photonsEnabled) return;

    Cooperate();

    if(strategy!=NULL)
    {
        delete strategy;
        sortPhotonMap();
    }
    else
    {
        if (!this->load())
            messageFactory.Error(POV_EXCEPTION_STRING("Failed to load photon map from disk"), "Could not load photon map (%s)",GetSceneData()->photonSettings.fileName);

        // set photon options automatically
        if (GetSceneData()->surfacePhotonMap.numPhotons>0)
            GetSceneData()->surfacePhotonMap.setGatherOptions(GetSceneData()->photonSettings,false);
        if (GetSceneData()->mediaPhotonMap.numPhotons>0)
            GetSceneData()->mediaPhotonMap.setGatherOptions(GetSceneData()->photonSettings,true);
    }

    // good idea to make sure all warnings and errors arrive frontend now [trf]
    SendProgress();
    Cooperate();
}
Example #5
0
void PhotonEstimationTask::Run()
{
	// quit right away if photons not enabled
	if (!GetSceneData()->photonSettings.photonsEnabled) return;

	if (GetSceneData()->photonSettings.surfaceCount==0) return;

	Cooperate();

	//  COUNT THE PHOTONS
	DBL factor;
	photonCountEstimate = 0.0;

	// global lights
	GetViewDataPtr()->Light_Is_Global = true;
	for(vector<LightSource *>::iterator Light = GetSceneData()->lightSources.begin(); Light != GetSceneData()->lightSources.end(); Light++)
	{
		if((*Light)->Light_Type != FILL_LIGHT_SOURCE)
			SearchThroughObjectsEstimatePhotons(GetSceneData()->objects, *Light);
	}

	// light_group lights
	/*
	TODO
	renderer->sceneData->photonSettings.Light_Is_Global = false;
	for(vector<LightSource *>::iterator Light_Group_Light = renderer->sceneData->lightGroupLights.begin(); Light_Group_Light != renderer->sceneData->lightGroupLights.end(); Light_Group_Light++)
	{
		Light = Light_Group_Light->Light;
		if (Light->Light_Type != FILL_LightSource)
		{
			SearchThroughObjectsEstimatePhotons(GetSceneData()->objects, *Light);
		}
	}
	*/

	factor = (DBL)photonCountEstimate/GetSceneData()->photonSettings.surfaceCount;
	factor = sqrt(factor);
	GetSceneData()->photonSettings.surfaceSeparation *= factor;


	// good idea to make sure all warnings and errors arrive frontend now [trf]
	Cooperate();
}
Example #6
0
/* loadPhotonMap()

  Loads the caustic photon map from a file.

  Preconditions:
    InitBacktraceEverything was called
    the photon map is empty
    renderer->sceneData->photonSettings.fileName contains the filename to load

  Postconditions:
    Returns 1 if success, 0 if failure.
    If success, the photon map has been loaded from the file.
    If failure then the render should stop with an error
*/
int PhotonSortingTask::load()
{
    int i;
    size_t err;
    Photon *ph;
    FILE *f;
    int numph;

    if (!GetSceneData()->photonSettings.photonsEnabled) return 0;

    messageFactory.Warning(kWarningGeneral,"Starting the load of photon file %s\n",GetSceneData()->photonSettings.fileName);

    f = fopen(GetSceneData()->photonSettings.fileName, "rb");
    if (!f) return 0;

    fread(&numph, sizeof(numph),1,f);

    for(i=0; i<numph; i++)
    {
        ph = GetSceneData()->surfacePhotonMap.AllocatePhoton();
        err = fread(ph, sizeof(Photon), 1, f);

        if (err<=0)
        {
            /* fread returned an error! */
            fclose(f);
            return 0;
        }
    }

    if (!feof(f)) /* for backwards file format compatibility */
    {

#ifdef GLOBAL_PHOTONS
        /* global photons */
        fread(&numph, sizeof(numph),1,f);
        for(i=0; i<numph; i++)
        {
            ph = GetSceneData()->globalPhotonMap.AllocatePhoton();
            err = fread(ph, sizeof(Photon), 1, f);

            if (err<=0)
            {
                /* fread returned an error! */
                fclose(f);
                return 0;
            }
        }
#endif

        /* media photons */
        fread(&numph, sizeof(numph),1,f);
        for(i=0; i<numph; i++)
        {
            ph = GetSceneData()->mediaPhotonMap.AllocatePhoton();
            err = fread(ph, sizeof(Photon), 1, f);

            if (err<=0)
            {
                /* fread returned an error! */
                fclose(f);
                return 0;
            }
        }

    }

    fclose(f);
    return true;
}
Example #7
0
/* savePhotonMap()

  Saves the caustic photon map to a file.

  Preconditions:
    InitBacktraceEverything was called
    the photon map has been built and balanced
    photonSettings.fileName contains the filename to save

  Postconditions:
    Returns 1 if success, 0 if failure.
    If success, the photon map has been written to the file.
*/
int PhotonSortingTask::save()
{
    Photon *ph;
    FILE *f;
    int i;
    size_t err;
    int numph;

    f = fopen(GetSceneData()->photonSettings.fileName, "wb");
    if (!f) return 0;

    /* caustic photons */
    numph = GetSceneData()->surfacePhotonMap.numPhotons;
    fwrite(&numph, sizeof(numph),1,f);
    if (numph>0 && GetSceneData()->surfacePhotonMap.head)
    {
        for(i=0; i<numph; i++)
        {
            ph = &(PHOTON_AMF(GetSceneData()->surfacePhotonMap.head, i));
            err = fwrite(ph, sizeof(Photon), 1, f);

            if (err<=0)
            {
                /* fwrite returned an error! */
                fclose(f);
                return 0;
            }
        }
    }
    else
    {
        messageFactory.PossibleError("Photon map for surface is empty.");
    }

#ifdef GLOBAL_PHOTONS
    /* global photons */
    numph = globalPhotonMap.numPhotons;
    fwrite(&numph, sizeof(numph),1,f);
    if (numph>0 && globalPhotonMap.head)
    {
        for(i=0; i<numph; i++)
        {
            ph = &(PHOTON_AMF(globalPhotonMap.head, i));
            err = fwrite(ph, sizeof(Photon), 1, f);

            if (err<=0)
            {
                /* fwrite returned an error! */
                fclose(f);
                return 0;
            }
        }
    }
    else
    {
        messageFactory.PossibleError("Global photon map is empty.");
    }
#endif

    /* media photons */
    numph = GetSceneData()->mediaPhotonMap.numPhotons;
    fwrite(&numph, sizeof(numph),1,f);
    if (numph>0 && GetSceneData()->mediaPhotonMap.head)
    {
        for(i=0; i<numph; i++)
        {
            ph = &(PHOTON_AMF(GetSceneData()->mediaPhotonMap.head, i));
            err = fwrite(ph, sizeof(Photon), 1, f);

            if (err<=0)
            {
                /* fwrite returned an error! */
                fclose(f);
                return 0;
            }
        }
    }
    else
    {
        messageFactory.PossibleError("Photon map for media is empty.");
    }

    fclose(f);
    return true;
}
Example #8
0
void PhotonSortingTask::sortPhotonMap()
{
    vector<PhotonMap*>::iterator mapIter;
    for(mapIter = surfaceMaps.begin(); mapIter != surfaceMaps.end(); mapIter++)
    {
        GetSceneData()->surfacePhotonMap.mergeMap(*mapIter);
        //delete (*mapIter);
    }
    for(mapIter = mediaMaps.begin(); mapIter != mediaMaps.end(); mapIter++)
    {
        GetSceneData()->mediaPhotonMap.mergeMap(*mapIter);
        //delete (*mapIter);
    }

    /* now actually build the kd-tree by sorting the array of photons */
    if (GetSceneData()->surfacePhotonMap.numPhotons>0)
    {
    //povwin::WIN32_DEBUG_FILE_OUTPUT("\n\nsurfacePhotonMap.buildTree about to be called\n");

        GetSceneData()->surfacePhotonMap.buildTree();
        GetSceneData()->surfacePhotonMap.setGatherOptions(GetSceneData()->photonSettings,false);
//      povwin::WIN32_DEBUG_FILE_OUTPUT("gatherNumSteps: %d\n",GetSceneData()->surfacePhotonMap.gatherNumSteps);
//      povwin::WIN32_DEBUG_FILE_OUTPUT("gatherRadStep: %lf\n",GetSceneData()->surfacePhotonMap.gatherRadStep);
//      povwin::WIN32_DEBUG_FILE_OUTPUT("minGatherRad: %lf\n",GetSceneData()->surfacePhotonMap.minGatherRad);
//      povwin::WIN32_DEBUG_FILE_OUTPUT("minGatherRadMult: %lf\n",GetSceneData()->surfacePhotonMap.minGatherRadMult);
//      povwin::WIN32_DEBUG_FILE_OUTPUT("numBlocks: %d\n",GetSceneData()->surfacePhotonMap.numBlocks);
//      povwin::WIN32_DEBUG_FILE_OUTPUT("numPhotons: %d\n",GetSceneData()->surfacePhotonMap.numPhotons);
    }

#ifdef GLOBAL_PHOTONS
    /* ----------- global photons ------------- */
    if (globalPhotonMap.numPhotons>0)
    {
        globalPhotonMap.buildTree();
        globalPhotonMap.setGatherOptions(false);
    }
#endif

    /* ----------- media photons ------------- */
    if (GetSceneData()->mediaPhotonMap.numPhotons>0)
    {
        GetSceneData()->mediaPhotonMap.buildTree();
        GetSceneData()->mediaPhotonMap.setGatherOptions(GetSceneData()->photonSettings,true);
    }

    if (GetSceneData()->surfacePhotonMap.numPhotons+
#ifdef GLOBAL_PHOTONS
        globalPhotonMap.numPhotons+
#endif
        GetSceneData()->mediaPhotonMap.numPhotons > 0)
    {
        /* should we load the photon map now that it is built? */
        if (GetSceneData()->photonSettings.fileName && !GetSceneData()->photonSettings.loadFile)
        {
            /* status bar for user */
//          Send_Progress("Saving Photon Maps", PROGRESS_SAVING_PHOTON_MAPS);
            if (!this->save())
                messageFactory.Warning(kWarningGeneral,"Could not save photon map.");
        }
    }
    else
    {
        if (GetSceneData()->photonSettings.fileName && !GetSceneData()->photonSettings.loadFile)
            messageFactory.Warning(kWarningGeneral,"Could not save photon map - no photons!");
    }
}
Example #9
0
}

RGBTColour& TraceTask::SubdivisionBuffer::operator()(size_t x, size_t y)
{
    return  colors[x + (y * size)];
}

void TraceTask::SubdivisionBuffer::Clear()
{
    for(vector<bool>::iterator i(sampled.begin()); i != sampled.end(); i++)
        *i = false;
}

TraceTask::TraceTask(ViewData *vd, unsigned int tm, DBL js, DBL aat, unsigned int aad, pov_base::GammaCurvePtr& aag, unsigned int ps, bool psc, bool final, bool hr) :
    RenderTask(vd, "Trace"),
    trace(vd->GetSceneData(), &vd->GetCamera(), GetViewDataPtr(), vd->GetSceneData()->parsedMaxTraceLevel, vd->GetSceneData()->parsedAdcBailout,
          vd->GetQualityFeatureFlags(), cooperate, media, radiosity),
    cooperate(*this),
    tracingMethod(tm),
    jitterScale(js),
    aaThreshold(aat),
    aaDepth(aad),
    aaGamma(aag),
    previewSize(ps),
    previewSkipCorner(psc),
    finalTrace(final),
    highReproducibility(hr),
    media(GetViewDataPtr(), &trace, &photonGatherer),
    radiosity(vd->GetSceneData(), GetViewDataPtr(),
              vd->GetSceneData()->radiositySettings, vd->GetRadiosityCache(), cooperate, final, vd->GetCamera().Location),
    photonGatherer(&vd->GetSceneData()->mediaPhotonMap, vd->GetSceneData()->photonSettings)