Custom textures

Hey

I've got a quick question.

Can anybody suggest a good way to take a grid of 2D data (ie f = f(x,y)) set and transform it into a texture which can then be applied to an AIS_Texture_Shape. This must be quite a common problem, but i really don't see how to go about it.

Is it possible to create a texture in mem. from a set of values or will I have to save out a *.bmp or *.jpg which can then be read in as a texture.

Any help would be fantastic !!

Teo

Francois Lauzon's picture

Hello Teo,
I had to create a new texture map derived from Graphic3d_TextureMap. In the constructor I did as follow:
RXAIS_TextureMap::RXAIS_TextureMap(const Handle(Graphic3d_StructureManager)& SM,
const Handle_TColStd_HArray2OfReal& aPixelsIn)
: Graphic3d_TextureMap(SM, "","", Graphic3d_TOT_2D_MIPMAP)
{
Handle_Image_ColorImage image=new Image_ColorImage(0,0,aPixelsIn->RowLength(),aPixelsIn->ColLength());

// fill the image with your values
// ....

Handle(AlienImage_BMPAlienImage) anAlienImage=new AlienImage_BMPAlienImage;
anAlienImage->FromImage(image);

LoadTexture(anAlienImage);

MyCInitTexture.doModulate = 1;
MyCInitTexture.doRepeat = 1;
MyCInitTexture.Mode = (int)Graphic3d_TOTM_MANUAL;
MyCInitTexture.doLinear = 1;
MyCInitTexture.sx = 1.0F;
MyCInitTexture.sy = 1.0F;
MyCInitTexture.tx = 0.0F;
MyCInitTexture.ty = 0.0F;
MyCInitTexture.angle = 0.0F;
MyCInitTexture.sparams[0] = 0.0F;
MyCInitTexture.sparams[1] = 0.0F;
MyCInitTexture.sparams[2] = 0.0F;
MyCInitTexture.sparams[3] = 0.0F;
MyCInitTexture.tparams[0] = 0.0F;
MyCInitTexture.tparams[1] = 0.0F;
MyCInitTexture.tparams[2] = 0.0F;
MyCInitTexture.tparams[3] = 0.0F;
Update();
}

I had to modify Graphic3d_TextureRoot.cxx so it didn't crash with a constructor that has no filename, and you have to recompile the Open Cascade library that use this file.

Here is the Graphic3d_TextureRoot.cxx modification:

Graphic3d_TextureRoot::Graphic3d_TextureRoot(const Handle(Graphic3d_StructureManager)& SM,const Standard_CString Path,const Standard_CString FileName,const Graphic3d_TypeOfTexture Type) : MyPath(FileName),MyType(Type)
{
#ifdef IMP140601
if( Path && (strlen(Path) > 0) )
#endif
MyPath.SetTrek(TCollection_AsciiString( Path ));

MyGraphicDriver = Handle(Graphic3d_GraphicDriver)::DownCast(SM->GraphicDevice()->GraphicDriver());

if (MyGraphicDriver->InquireTextureAvailable())
{
// chargement de l'image
//-GG Handle(AlienImage_AlienImage) MyImage = LoadTexture();
if (MyImage.IsNull() && FileName && (strlen(FileName) > 0))
MyImage = LoadTexture();

if (MyImage.IsNull()) {
MyTexId = -1;
return;
}

MyTexId = MyGraphicDriver->CreateTexture(Type, MyImage, FileName);
}
#ifdef TRACE
printf(" *** Graphic3d_TextureRoot::Create() textId %d\n",MyTexId);
#endif
}

Good luck,
Francois.

teoshaw's picture

So nice and easy then ;)

Thanks muchness for the help, i'll give it a go

Teo

teoshaw's picture

Hey

I tried that and had some problems. I made your changes to the TKV3d lib but it didn\'t seem to help. I still got a crash. However i inherited from Graphic3d_Texture2Dmanual and that seemed to work

then I have

Standard_CString fileName(\"1\");
TCollection_AsciiString aText(fileName);

Handle_AIS_TexturedShape aAIS_T_Shape = new AIS_TexturedShape(aShape);

Handle(Graphic3d_Texture2Dmanual) aTexture = new RXAIS_TextureMap
(
theViewer->Viewer(),
(Graphic3d_NameOfTexture2D) 1
);

aAIS_T_Shape->SetTextureFileName(aText);

With the new constructer

RXAIS_TextureMap::RXAIS_TextureMap(const Handle(Graphic3d_StructureManager)& SM, Graphic3d_NameOfTexture2D name)
: Graphic3d_Texture2Dmanual(SM, name)
{
Handle_Image_ColorImage image = new Image_ColorImage(0,0,10,10);

for(int i=0;i<10;i++)
{
for(int j=0;j<10;j++)
{
Quantity_Parameter R1 = 1.0 - ((float)i)/((float)10-1);
Quantity_Parameter R2 = 0.0;
Quantity_Parameter R3 = ((float)j)/((float)10-1);

Quantity_Color aColor(R1,R2,R3,Quantity_TOC_RGB);
Aspect_ColorPixel aColorPixel(aColor);

image->SetPixel(i,j,aColorPixel);
}
}

Handle(AlienImage_BMPAlienImage) anAlienImage = new AlienImage_BMPAlienImage;
anAlienImage->FromImage(image);

LoadTexture(anAlienImage);

MyCInitTexture.doModulate = 1;
MyCInitTexture.doRepeat = 1;
MyCInitTexture.Mode = (int)Graphic3d_TOTM_MANUAL;
MyCInitTexture.doLinear = 1;
MyCInitTexture.sx = 1.0F;
MyCInitTexture.sy = 1.0F;
MyCInitTexture.tx = 0.0F;
MyCInitTexture.ty = 0.0F;
MyCInitTexture.angle = 0.0F;

MyCInitTexture.sparams[0] = 0.0F;
MyCInitTexture.sparams[1] = 0.0F;
MyCInitTexture.sparams[2] = 0.0F;
MyCInitTexture.sparams[3] = 0.0F;
MyCInitTexture.tparams[0] = 0.0F;
MyCInitTexture.tparams[1] = 0.0F;
MyCInitTexture.tparams[2] = 0.0F;
MyCInitTexture.tparams[3] = 0.0F;

Update();
}

but I get the default texture applied to my shape. Is there something I haven\'t done? For example have i failed to apply the texture to the surface?

This seems to be the only way to do it.

If you have any ideas.....

Teo

Francois Lauzon's picture

Hello Teo,
It look pretty much like what I did. I didn't derive from Graphic3d_Texture2Dmanual, my class is at the same level has Graphic3d_Texture2Dmanual except I load an image, if you look at both constructor source code, you will see there are very similar. And I didn't use the class AIS_TexturedShape (you can't if you want to use a new texture which is not file based).

- I use Open Cascade 5.2.3... I know there has been bug fix and work done on texture map since version 5.2, so I don't know which version you are using...

- You need to enabled V3d_TEX_ALL in you viewer and view.

- You need to set SetTextureMapOn() and SetDisplayMode(3) on you TexturedShape.

- You need to create you own class similar to AIS_TexturedShape, in which you use you own texture instead of the Graphic3d_Texture2Dmanual (look at line 231,233,353 and 355 in the file AIS_TexturedShape.cxx).

I think it all, unless I forgot something else...

Good Luck,
Francois.