POV-Ray : Newsgroups : povray.general : Can textures be applied to nested objects from outside? Server Time
28 Mar 2024 13:59:50 EDT (-0400)
  Can textures be applied to nested objects from outside? (Message 1 to 4 of 4)  
From: kendfrey
Subject: Can textures be applied to nested objects from outside?
Date: 23 Jan 2019 18:05:00
Message: <web.5c48ed2fe639bd6ec059c35f0@news.povray.org>
I have a composite object (union) in a declared identifier, and my scene will
contain many copies of that object. What I need is a way to specify the texture
for the various components of the object, per copy, without having to
reconstruct the object every time.

For example, suppose my object is the figure of a person, with components for
the person's hair, skin, and clothing. The goal is to be able to place the
figure multiple times in the scene, with different hair, skin, and clothing for
each instance.

I haven't been able to find a straightforward way to do this. Here are some
things I considered:
- Using a macro instead of declaring the object. This would bloat the code quite
significantly, since each component would need to be stored separately in its
own identifier, and recombined every time it's used.
- UV mapping with non-overlapping UV ranges per component. Unfortunately this
isn't supported by every type of object, and it may conflict* with other parts
of the scene.
- Temporarily using the #default texture. This won't work properly with multiple
components, though.

What I'd like is something like this, where identifiers are evaluated when the
object is added to the scene:

#declare Foo = union
{
    sphere
    {
        <0, 0, 0>, 1
        pigment { SpherePigment }
    }
    box
    {
        <0, 0, 0>, <1, 1, 1>
        pigment { BoxPigment }
    }
}
#declare SpherePigment = pigment { color Red }
#declare BoxPigment = pigment { color Blue }
object { Foo } // A red sphere and a blue box

Is there something I missed, or is this impossible in general?


* I eventually hope to use UV mapping (or something similar) in a way that
selects from a 3D texture map instead of directly wrapping a 2D texture onto the
surface. This is to avoid artifacts that would be caused by tiling a fixed 2D
image. I don't know if this is relevant to the main question, but I'm including
it for completeness.


Post a reply to this message

From: Alain
Subject: Re: Can textures be applied to nested objects from outside?
Date: 23 Jan 2019 18:58:51
Message: <5c48ffbb$1@news.povray.org>
Le 19-01-23 à 18:02, kendfrey a écrit :
> I have a composite object (union) in a declared identifier, and my scene will
> contain many copies of that object. What I need is a way to specify the texture
> for the various components of the object, per copy, without having to
> reconstruct the object every time.
> 
> For example, suppose my object is the figure of a person, with components for
> the person's hair, skin, and clothing. The goal is to be able to place the
> figure multiple times in the scene, with different hair, skin, and clothing for
> each instance.
> 
> I haven't been able to find a straightforward way to do this. Here are some
> things I considered:
> - Using a macro instead of declaring the object. This would bloat the code quite
> significantly, since each component would need to be stored separately in its
> own identifier, and recombined every time it's used.
> - UV mapping with non-overlapping UV ranges per component. Unfortunately this
> isn't supported by every type of object, and it may conflict* with other parts
> of the scene.
> - Temporarily using the #default texture. This won't work properly with multiple
> components, though.
> 
> What I'd like is something like this, where identifiers are evaluated when the
> object is added to the scene:
> 
> #declare Foo = union
> {
>      sphere
>      {
>          <0, 0, 0>, 1
>          pigment { SpherePigment }
>      }
>      box
>      {
>          <0, 0, 0>, <1, 1, 1>
>          pigment { BoxPigment }
>      }
> }
> #declare SpherePigment = pigment { color Red }
> #declare BoxPigment = pigment { color Blue }
> object { Foo } // A red sphere and a blue box
> 
> Is there something I missed, or is this impossible in general?
> 
> 
> * I eventually hope to use UV mapping (or something similar) in a way that
> selects from a 3D texture map instead of directly wrapping a 2D texture onto the
> surface. This is to avoid artifacts that would be caused by tiling a fixed 2D
> image. I don't know if this is relevant to the main question, but I'm including
> it for completeness.
> 
> 

The best way would be a macro. The macro would get the various colours 
as parameters, of from global variables set before it's invocation.
Also, the dominant texture could be left undefined. This allow it to be 
applied as follow :
#macro Foo =(C1)
  union{
     sphere
     {
         <0, 0, 0>, 1
         pigment { C1 }
     }
     box
     {
         <0, 0, 0>, <1, 1, 1>
     }
}
#end

#declare SpherePigment = pigment { color Red }
#declare MainPigment = pigment { color Blue }

object{Foo(SpherePigment) pigment{MainPigment }}


Post a reply to this message

From: clipka
Subject: Re: Can textures be applied to nested objects from outside?
Date: 24 Jan 2019 06:43:24
Message: <5c49a4dc$1@news.povray.org>
Am 24.01.2019 um 00:02 schrieb kendfrey:

> I haven't been able to find a straightforward way to do this. Here are some
> things I considered:
> - Using a macro instead of declaring the object. This would bloat the code quite
> significantly, since each component would need to be stored separately in its
> own identifier, and recombined every time it's used.

This is the approach I would recommend.

You can get around the problem of cluttering up global namespace with 
gazillions of identifiers, by making use of a dictionary to store the 
components, like so:

     #declare MyComponents = dictionary;

     #declare MyComponents.Body = mesh { ... }
     #declare MyComponents.Hair = mesh { ... }


> * I eventually hope to use UV mapping (or something similar) in a way that
> selects from a 3D texture map instead of directly wrapping a 2D texture onto the
> surface. This is to avoid artifacts that would be caused by tiling a fixed 2D
> image. I don't know if this is relevant to the main question, but I'm including
> it for completeness.

You can always scale and translate a 3D texture to get a different 
"chunk" of it, if that's what you're after; and there are creative ways 
to nest patterned textures so that different "chunks" of the texture 
would have entirely different properties.


Post a reply to this message

From: kendfrey
Subject: Re: Can textures be applied to nested objects from outside?
Date: 24 Jan 2019 17:30:01
Message: <web.5c4a3be1a5633490c059c35f0@news.povray.org>
clipka <ano### [at] anonymousorg> wrote:
> This is the approach I would recommend.
>
> You can get around the problem of cluttering up global namespace with
> gazillions of identifiers, by making use of a dictionary to store the
> components, like so:
>
>      #declare MyComponents = dictionary;
>
>      #declare MyComponents.Body = mesh { ... }
>      #declare MyComponents.Hair = mesh { ... }

After updating to 3.7.1, refactoring to use dictionaries, and general tweaking,
the macro approach is working. It's not as clean as I'd hoped but it does the
job.


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.