int Post_Pigment(PIGMENT *Pigment) { int i, Has_Filter; BLEND_MAP *Map; if (Pigment == NULL) { throw POV_EXCEPTION_STRING("Missing pigment"); } if (Pigment->Flags & POST_DONE) { return(Pigment->Flags & HAS_FILTER); } if (Pigment->Type == NO_PATTERN) { Pigment->Type = PLAIN_PATTERN; Pigment->colour.clear() ; ;// TODO MESSAGE Warning(150, "No pigment type given."); } Pigment->Flags |= POST_DONE; switch (Pigment->Type) { case PLAIN_PATTERN: Destroy_Warps (Pigment->Warps); Pigment->Warps = NULL; break; case NO_PATTERN: case BITMAP_PATTERN: break; default: if (Pigment->Blend_Map == NULL) { switch (Pigment->Type) { // NB: The const default blend maps are marked so that they will not be modified nor destroyed later. case BOZO_PATTERN: Pigment->Blend_Map = const_cast<BLEND_MAP *>(&Bozo_Default_Map); break; case BRICK_PATTERN: Pigment->Blend_Map = const_cast<BLEND_MAP *>(&Brick_Default_Map); break; case WOOD_PATTERN: Pigment->Blend_Map = const_cast<BLEND_MAP *>(&Wood_Default_Map); break; case MANDEL_PATTERN: Pigment->Blend_Map = const_cast<BLEND_MAP *>(&Mandel_Default_Map);break; case RADIAL_PATTERN: Pigment->Blend_Map = const_cast<BLEND_MAP *>(&Radial_Default_Map);break; case AGATE_PATTERN: Pigment->Blend_Map = const_cast<BLEND_MAP *>(&Agate_Default_Map); break; case MARBLE_PATTERN: Pigment->Blend_Map = const_cast<BLEND_MAP *>(&Marble_Default_Map);break; case HEXAGON_PATTERN: Pigment->Blend_Map = const_cast<BLEND_MAP *>(&Hex_Default_Map); break; case SQUARE_PATTERN: Pigment->Blend_Map = const_cast<BLEND_MAP *>(&Square_Default_Map);break; case TRIANGULAR_PATTERN: Pigment->Blend_Map = const_cast<BLEND_MAP *>(&Triangular_Default_Map);break; case CUBIC_PATTERN: Pigment->Blend_Map = const_cast<BLEND_MAP *>(&Cubic_Default_Map); break; // JN2007: Cubic pattern case CHECKER_PATTERN: Pigment->Blend_Map = const_cast<BLEND_MAP *>(&Check_Default_Map); break; case AVERAGE_PATTERN: break;// TODO MESSAGE Error("Missing pigment_map in average pigment"); break; case OBJECT_PATTERN: Pigment->Blend_Map = const_cast<BLEND_MAP *>(&Check_Default_Map); break; default: Pigment->Blend_Map = const_cast<BLEND_MAP *>(&Gray_Default_Map); break; } } break; } /* Now we test wether this pigment is opaque or not. [DB 8/94] */ Has_Filter = false; if ((fabs(Pigment->colour[pFILTER]) > EPSILON) || (fabs(Pigment->colour[pTRANSM]) > EPSILON)) { Has_Filter = true; } if ((Pigment->Type == BITMAP_PATTERN) && (Pigment->Vals.image != NULL)) { // bitmaps are transparent if they are used only once, or the image is not opaque Has_Filter |= (Pigment->Vals.image->Once_Flag) || !is_image_opaque(Pigment->Vals.image); } if ((Map = Pigment->Blend_Map) != NULL) { if ((Map->Type == PIGMENT_TYPE) || (Map->Type == DENSITY_TYPE)) { for (i = 0; i < Map->Number_Of_Entries; i++) { Has_Filter |= Post_Pigment(Map->Blend_Map_Entries[i].Vals.Pigment); } } else { for (i = 0; i < Map->Number_Of_Entries; i++) { Has_Filter |= fabs(Map->Blend_Map_Entries[i].Vals.colour[pFILTER])>EPSILON; Has_Filter |= fabs(Map->Blend_Map_Entries[i].Vals.colour[pTRANSM])>EPSILON; } } } if (Has_Filter) { Pigment->Flags |= HAS_FILTER; } if (Pigment->Next != NULL) { Post_Pigment(reinterpret_cast<PIGMENT *>(Pigment->Next)); } return(Has_Filter); }
void Post_Pigment(PIGMENT *Pigment, bool* pHasFilter) { bool hasFilter; if (Pigment == NULL) { throw POV_EXCEPTION_STRING("Missing pigment"); } if (Pigment->Flags & POST_DONE) { if ((pHasFilter != NULL) && (Pigment->Flags & HAS_FILTER)) *pHasFilter = true; return; } if (Pigment->Type == NO_PATTERN) { Pigment->Type = PLAIN_PATTERN; Pigment->colour.Clear() ; ;// TODO MESSAGE Warning(150, "No pigment type given."); } Pigment->Flags |= POST_DONE; switch (Pigment->Type) { case NO_PATTERN: assert(false); // should have been forced to PLAIN_PATTERN by now break; case PLAIN_PATTERN: case BITMAP_PATTERN: break; default: if (Pigment->Blend_Map == NULL) { switch (Pigment->Type) { // NB: The const default blend maps are marked so that they will not be modified nor destroyed later. case AVERAGE_PATTERN: // TODO MESSAGE Error("Missing pigment_map in average pigment"); break; default: Pigment->Blend_Map = std::tr1::static_pointer_cast<GenericPigmentBlendMap, ColourBlendMap>( std::tr1::const_pointer_cast<ColourBlendMap, const ColourBlendMap>( Pigment->pattern->GetDefaultBlendMap())); break; } } break; } /* Now we test wether this pigment is opaque or not. [DB 8/94] */ hasFilter = false; if (!Pigment->colour.TransmittedColour().IsNearZero(EPSILON)) { hasFilter = true; } if ((Pigment->Type == BITMAP_PATTERN) && (dynamic_cast<ImagePattern*>(Pigment->pattern.get())->pImage != NULL)) { // bitmaps are transparent if they are used only once, or the image is not opaque if ((dynamic_cast<ImagePattern*>(Pigment->pattern.get())->pImage->Once_Flag) || !is_image_opaque(dynamic_cast<ImagePattern*>(Pigment->pattern.get())->pImage)) hasFilter = true; } GenericPigmentBlendMap* Map = Pigment->Blend_Map.get(); if (Map != NULL) { Map->Post(hasFilter); } if (hasFilter) { Pigment->Flags |= HAS_FILTER; if (pHasFilter != NULL) *pHasFilter = true; } }