Example #1
0
void Build_Light_Buffers()
{
  int Axis;
  PROJECT Project;
  LIGHT_SOURCE *Light;
  int proj_thru;
  PROJECT proj_proj;

  if (!(opts.Quality_Flags & Q_SHADOW) || (!opts.Use_Slabs))
  {
    opts.Options &= ~USE_LIGHT_BUFFER;
  }

  if (opts.Options & USE_LIGHT_BUFFER)
  {
    Send_Progress("Creating light buffers", PROGRESS_CREATE_LIGHT_BUFFERS);
    /*YS 29 april 2000 bugfix*/
    BuffersInit=true;
    /*YS 29 april 2000 bugfix*/
    /* Build the light buffer for all point(!) light sources */
  
    for (Light = Frame.Light_Sources; Light != NULL; Light = Light->Next_Light_Source)
    {
      if ((!Light->Area_Light) && (Light->Light_Type!=FILL_LIGHT_SOURCE) && 
          !(Light->Parallel))
      {
        Send_ProgressUpdate(PROGRESS_CREATE_LIGHT_BUFFERS);

        /* Project bounding slabs on all six sides */
        for (Axis = 0; Axis < 6; Axis++)
        {
          if ( Light->Projected_Through_Object ) {
            proj_thru=1;
            project_object (&proj_proj, Light->Projected_Through_Object, Axis, Light->Center, 0, NULL);
          }
          else {
            proj_thru=0;
          }
          Light->Light_Buffer[Axis] = NULL;
          if ( !proj_thru || ((proj_proj.x1 <= proj_proj.x2) && (proj_proj.y1 <= proj_proj.y2))) {
            project_bounding_slab(Axis, Light->Center, &Project,
              &Light->Light_Buffer[Axis], Root_Object, proj_thru, &proj_proj);
          }
        }
      }
    }
  }
}
Example #2
0
SHELLRET pov_shellout (SHELLTYPE Type)
{
  char real_command[POV_MAX_CMD_LENGTH];
  int i, j, l = 0;
  int length;
  SHELLRET Return_Code;
  char *s = NULL;
  char *template_command;


  if ( opts.Shellouts == NULL ) return(IGNORE_RET);

  template_command=opts.Shellouts[Type].Command;

  if ((length = strlen(template_command)) == 0)
  {
    return(IGNORE_RET);
  }

  switch(Type)
  {
    case PRE_SCENE_SHL:  s="pre-scene";   break;
    case PRE_FRAME_SHL:  s="pre-frame";   break;
    case POST_FRAME_SHL: s="post-frame";  break;
    case POST_SCENE_SHL: s="post-scene";  break;
    case USER_ABORT_SHL: s="user about";  break;
    case FATAL_SHL:      s="fatal error"; break;
    case MAX_SHL: /* To remove warnings*/ break;
  }

  Send_Progress(pov_tsprintf("Performing %s shell-out command", s), PROGRESS_PERFORMING_SHELLOUT_COMMAND);

  /* First, find the real command */

  for (i = 0, j = 0; i < length; )
  {
    if (template_command[i] == '%')
    {
      switch (toupper(template_command[i+1]))
      {
         case 'O':

          strncpy(&real_command[j], opts.Output_Numbered_Name, 
               (unsigned)(l=strlen(opts.Output_Numbered_Name)));

          break;

         case 'P':

          strncpy(&real_command[j], opts.Output_Path,(unsigned)(l=strlen(opts.Output_Path)));

          break;

         case 'S':

          strncpy(&real_command[j], opts.Scene_Name, (unsigned)(l=strlen(opts.Scene_Name)));

          break;

         case 'N':

          sprintf(&real_command[j],"%d",opts.FrameSeq.FrameNumber);
          l = strlen(&real_command[j]);

          break;

         case 'K':

          sprintf(&real_command[j],"%f",opts.FrameSeq.Clock_Value);
          l = strlen(&real_command[j]);

          break;

         case 'H':

          sprintf(&real_command[j],"%d",Frame.Screen_Height);
          l = strlen(&real_command[j]);

          break;

         case 'W':

          sprintf(&real_command[j],"%d",Frame.Screen_Width);
          l = strlen(&real_command[j]);

          break;

         case '%':

          real_command[j]='%';

          l=1;

          break;
       }

       j+=l;

       i+=2; /* we used 2 characters of template_command */
    }
    else
    {
      real_command[j++]=template_command[i++];
    }
  }

  real_command[j]='\0';

  Return_Code=(POV_SHELLOUT_CAST)POV_SYSTEM(real_command);

  if (opts.Shellouts[Type].Inverse)
  {
    Return_Code=(POV_SHELLOUT_CAST)(!((int)Return_Code));
  }

  if (Return_Code)
  {
    if (Type < USER_ABORT_SHL)
    {
      switch(opts.Shellouts[Type].Ret)
      {
        case FATAL_RET:

          Error("Fatal error returned from shellout command.");

          break;

        case USER_RET:

          Check_User_Abort(true); /* the true forces user abort */

          break;

        case QUIT_RET:

          povray_exit(0);

          break;

        case IGNORE_RET:
        case SKIP_ONCE_RET:
        case ALL_SKIP_RET: /* Added to remove warnings */
          break;
      }
    }

    return(opts.Shellouts[Type].Ret);
  }

  return(IGNORE_RET);
}
Example #3
0
/* Released all unfree'd memory from all pools */
void mem_release_all()
{
#if defined(MEM_RECLAIM)
  OStream *f = NULL;
  MEMNODE *p, *tmp;
  size_t totsize;

  Send_Progress("Reclaiming memory", PROGRESS_RECLAIMING_MEMORY);

  p = memlist;
  totsize = 0;

#if defined(MEM_TRACE)
  if (p != NULL)
    f = New_OStream(MEM_LOG_FNAME, POV_File_Data_LOG, true);
#endif

  while (p != NULL)
  {
#if defined(MEM_TRACE)

    #if defined(MEM_TAG)
    if (!mem_check_tag(p))
      Debug_Info("mem_release_all(): Memory pointer corrupt!\n");
    #endif /* MEM_TAG */

    totsize += (p->size - NODESIZE - (MEM_GUARD_SIZE * 2));
    if (!leak_msg)
    {
      Debug_Info("Memory leakage detected, see file '%s' for list\n",MEM_LOG_FNAME);
      leak_msg = true;
    }

    if (f != NULL)
      f->printf("File:%13s  Line:%4d  Size:%lu\n", p->file, p->line, (unsigned long)(p->size - NODESIZE - (MEM_GUARD_SIZE * 2)));
#endif

#if defined(MEM_STATS)
    /* This is after we have printed stats, and this may slow us down a little,      */
    /* so we may want to simply re-initialize the mem-stats at the end of this loop. */
    mem_stats_free(p->size);
#endif

    tmp = p;
    p = p->next;
    remove_node(tmp);
    FREE(tmp);
  }

  if (f != NULL)
    delete f;

  if (totsize > 0)
    Debug_Info("\n%lu bytes reclaimed\n", totsize);

  poolno = 0;
  memlist = NULL;
#endif

#if defined(MEM_STATS)
  /* reinitialize the stats structure for next time through */
  mem_stats_init();
#endif

}
Example #4
0
void FrameRender()
{
   // Store start time for parse.
   START_TIME

   Current_Token_Count = 0;
   tparse_frame = tphoton_frame = trender_frame = 0.0;

   // Parse the scene file.
   Send_Progress("Parsing", PROGRESS_PARSING);

   opts.Do_Stats = false;

   // Set up noise-tables
   Initialize_Noise();

   // Set up function VM
   POVFPU_Init();

   // Init module specific stuff.
   Initialize_Mesh_Code();

   Parse();

   opts.Do_Stats = true;

   if (opts.Radiosity_Enabled)
      Experimental_Flag |= EF_RADIOS;

   if (Experimental_Flag)
   {
      char str[512] = "" ;

      if (Experimental_Flag & EF_SPLINE)
        strcat (str, str [0] ? ", spline" : "spline") ;
      if (Experimental_Flag & EF_RADIOS)
        strcat (str, str [0] ? ", radiosity" : "radiosity") ;
      if (Experimental_Flag & EF_SLOPEM)
        strcat (str, str [0] ? ", slope pattern" : "slope pattern") ;
      if (Experimental_Flag & EF_ISOFN) 
        strcat (str, str [0] ? ", function '.hf'" : "function '.hf'") ;
      if (Experimental_Flag & EF_TIFF) 
        strcat (str, str [0] ? ", TIFF image support" : "TIFF image support") ;

      Warning(0, "This rendering uses the following experimental feature(s): %s.\n"
                 "The design and implementation of these features is likely to change in future versions\n"
                 "of POV-Ray. Full backward compatibility with the current implementation is NOT guaranteed.",
                 str);
   }

   Experimental_Flag = 0;

   // Switch off standard anti-aliasing.

   if((Frame.Camera->Aperture != 0.0) && (Frame.Camera->Blur_Samples > 0))
   {
      opts.Options &= ~ANTIALIAS;

      Warning(0, "Focal blur is used. Standard antialiasing is switched off.");
   }

   // Create the bounding box hierarchy.

   Stage = STAGE_SLAB_BUILDING;

   if(opts.Use_Slabs)
      Send_Progress("Creating bounding slabs", PROGRESS_CREATING_BOUNDING_SLABS);

   // Init module specific stuff.
   Initialize_Atmosphere_Code();
   Initialize_BBox_Code();
   Initialize_Lighting_Code();
   Initialize_VLBuffer_Code();
   Initialize_Radiosity_Code();

   // Always call this to print number of objects.
   Build_Bounding_Slabs(&Root_Object);

   // Create the vista buffer.
   Build_Vista_Buffer();

   // Create the light buffers.
   Build_Light_Buffers();

   // Save variable values.
   variable_store(STORE);

   // Get the parsing time.
   STOP_TIME
   tparse = TIME_ELAPSED
   Send_ProgressUpdate(PROGRESS_PARSING, 0);

   // Output parsing statistics.
   Send_ParseStatistics();

   if (photonOptions.photonsEnabled)
   {
     /* Store start time for photons. */
     START_TIME

     /* now backwards-trace the scene and build the photon maps */
     InitBacktraceEverything();
     BuildPhotonMaps();

     /* Get the photon-shooting time. */
     STOP_TIME
     tphoton = TIME_ELAPSED

     /* Get total parsing time. */
     tphoton_total += tphoton;
     tphoton_frame = tphoton;
     tphoton = 0;
   }

   /* Store start time for the rest of parsing. */
   START_TIME
   Stage = STAGE_INIT;

   // Open output file and if we are continuing an interrupted trace,
   // read in the previous file settings and any data there.  This has to
   // be done before any image-size related allocations, since the settings
   // in a resumed file take precedence over that specified by the user. [AED]
   open_output_file();

   // Start the display.
   if(opts.Options & DISPLAY)
   {
      Send_Progress("Displaying", PROGRESS_DISPLAYING);

      Display_Started = POV_DISPLAY_INIT(opts.Preview_RefCon, Frame.Screen_Width, Frame.Screen_Height);

      // Display vista tree.
      Draw_Vista_Buffer();
   }
   else
   {
      Display_Started = false;
   }

   // Get things ready for ray tracing (misc init, mem alloc)
   Initialize_Renderer();

   // This had to be taken out of open_output_file() because we don't have
   // the final image size until the output file has been opened, so we can't
   // initialize the display until we know this, which in turn means we can't
   // read the rendered part before the display is initialized. [AED]
   if((opts.Options & DISKWRITE) && (opts.Options & CONTINUE_TRACE))
   {
      Read_Rendered_Part(Actual_Output_Name);

      if (opts.Last_Line > Frame.Screen_Height)
         opts.Last_Line = Frame.Screen_Height;

      if (opts.Last_Column > Frame.Screen_Width)
         opts.Last_Column = Frame.Screen_Width;
   }

   // Get the rest of the parsing time.
   STOP_TIME
   tparse += TIME_ELAPSED

   // Store start time for trace.
   START_TIME

   // Get total parsing time.
   tparse_total += tparse;
   tparse_frame = tparse;
   tparse = 0;

   // Start tracing.
   Stage = STAGE_RENDERING;

   POV_PRE_RENDER

   Send_Progress("Rendering", PROGRESS_RENDERING);

   // Macro for setting up any special FP options
   CONFIG_MATH

   // Ok, go for it - trace the picture.

   // If radiosity preview has been done, we are continuing a trace, so it
   // is important NOT to do the preview, even if the user requests it, as it
   // will cause discontinuities in radiosity shading by (probably) calculating
   // a few more radiosity values.

   // Note that radiosity REQUIRES a mosaic preview prior to main scan
   if ( opts.Radiosity_Enabled && !opts.Radiosity_Preview_Done)
      Start_Tracing_Radiosity_Preview(opts.PreviewGridSize_Start, opts.PreviewGridSize_End);

   else if((opts.Options & PREVIEW) && (opts.Options & DISPLAY))
      Start_Tracing_Mosaic_Preview(opts.PreviewGridSize_Start, opts.PreviewGridSize_End);

   switch(opts.Tracing_Method)
   {
      case 2:
         Start_Adaptive_Tracing();
         break;
      case 1:
      default:
         Start_Non_Adaptive_Tracing();
   }

   // Record time so well spent before file close so it can be in comments
   STOP_TIME
   trender = TIME_ELAPSED

   // shutdown (freeing memory) does not get included in the time!

   // Get total render time.
   trender_total += trender;
   trender_frame = trender;
   trender = 0;

   // Close out our file
   if(Output_File != NULL)
   {
      delete Output_File;
      Output_File = NULL;
   }

   // For all those who never rtfm [trf]
   if((Highest_Trace_Level >= Max_Trace_Level) && (Had_Max_Trace_Level == false))
      PossibleError("Maximum trace level reached! If your scene contains black spots\nread more about the max_trace_level setting in the documentation!");

   Stage = STAGE_SHUTDOWN;

   POV_PRE_SHUTDOWN

   // DESTROY lots of stuff
   /* NK phmap */
   FreeBacktraceEverything();
   Deinitialize_Atmosphere_Code();
   Deinitialize_BBox_Code();
   Deinitialize_Lighting_Code();
   Deinitialize_Mesh_Code();
   Deinitialize_VLBuffer_Code();
   Deinitialize_Radiosity_Code();
   Destroy_Light_Buffers();
   Destroy_Vista_Buffer();
   Destroy_Bounding_Slabs();
   Destroy_Frame();
   Terminate_Renderer();
   FreeFontInfo();
   Free_Iteration_Stack();
   Free_Noise_Tables();

   POVFPU_Terminate();

   POV_POST_SHUTDOWN

   if((opts.Options & DISPLAY) && Display_Started)
   {
      POV_DISPLAY_FINISHED(opts.Preview_RefCon);

      POV_DISPLAY_CLOSE(opts.Preview_RefCon);

      Display_Started = false;
   }

   if(opts.histogram_on)
      write_histogram(opts.Histogram_File_Name);

   Send_Progress("Done Tracing", PROGRESS_DONE_TRACING);

   // Print stats ...
   Send_RenderStatistics();

   if(opts.FrameSeq.FrameType == FT_MULTIPLE_FRAME)
   {
      // Add them up
      sum_statistics(totalstats, stats);

      // ... and then clear them for the next frame
      init_statistics(stats);
   }

   // Restore variable values.
   variable_store(RESTORE);
}
Example #5
0
void FrameLoop()
{
   int Diff_Frame;
   DBL Diff_Clock;
   SHELLRET Pre_Scene_Result, Frame_Result;

   Diff_Clock = opts.FrameSeq.FinalClock - opts.FrameSeq.InitialClock;

   if(opts.Options & CYCLIC_ANIMATION)
      Diff_Frame = opts.FrameSeq.FinalFrame - opts.FrameSeq.InitialFrame + 1;
   else
      Diff_Frame = opts.FrameSeq.FinalFrame - opts.FrameSeq.InitialFrame;

   Clock_Delta = ((Diff_Frame == 0) ? 0 : Diff_Clock/Diff_Frame);

   // Execute the first shell-out command
   Pre_Scene_Result = (POV_SHELLOUT_CAST)POV_SHELLOUT(PRE_SCENE_SHL);

   // Loop over each frame

   if(Pre_Scene_Result != ALL_SKIP_RET)
   {
      if(Pre_Scene_Result != SKIP_ONCE_RET)
      {
         for(opts.FrameSeq.FrameNumber = opts.FrameSeq.InitialFrame,
             opts.FrameSeq.Clock_Value = opts.FrameSeq.InitialClock;

             opts.FrameSeq.FrameNumber <= opts.FrameSeq.FinalFrame;

             // ISO/IEC 14882:1998(E) section 5.18 Comma operator [expr.comma] (page 90) says
             // that comma expressions are evaluated left-to-right, and according to section
             // 6.5.3 The for statement [stmt.for] (page 97) the following is an expression.
             // I just hope all compilers really know about the standard... [trf]
             opts.FrameSeq.FrameNumber++,
             opts.FrameSeq.Clock_Value = opts.FrameSeq.InitialClock +
               (Clock_Delta * (DBL)(opts.FrameSeq.FrameNumber - opts.FrameSeq.InitialFrame)))
         {
            if(opts.FrameSeq.FrameType == FT_MULTIPLE_FRAME)
            {
               START_TIME
               Send_Progress("Processing Frame", PROGRESS_PROCESSING_FRAME);
            }

            setup_output_file_name();

            // Execute a shell-out command before tracing

            Frame_Result = (POV_SHELLOUT_CAST)POV_SHELLOUT(PRE_FRAME_SHL);

            if(Frame_Result == ALL_SKIP_RET)
               break;

            if(Frame_Result != SKIP_ONCE_RET)
            {
               FrameRender();

               // Execute a shell-out command after tracing

               Frame_Result = (POV_SHELLOUT_CAST)POV_SHELLOUT(POST_FRAME_SHL);
           
               if((Frame_Result == SKIP_ONCE_RET) || (Frame_Result == ALL_SKIP_RET))
                  break;
            }

            if(opts.FrameSeq.FrameType == FT_MULTIPLE_FRAME)
               Send_FrameStatistics();

            Do_Cooperate(1);
         }

         // Print total stats ...

         if(opts.FrameSeq.FrameType == FT_MULTIPLE_FRAME)
         {
            opts.FrameSeq.FrameNumber--;

            Send_RenderStatistics(true);

            opts.FrameSeq.FrameNumber++;
         }
      }

      // Execute the final shell-out command
      POV_SHELLOUT(POST_SCENE_SHL);
   }
}