OpenCasCade – 贴纹理

前言

因为项目需要,所以最近研究了下给 用OpenCasCade库创建的模型贴纹理的问题。因为网上没找到相关的文章,特此记录下来。

官方示例

本文中的代码是完全仿照官方示例(All-vc10 中的 Viewer3d)所写的,筒子们可以自己去研究一下这块代码,如图:

2015-03-07_153525

 

然后看下官方示例的贴纹理效果:

sampleBottle

 

sampleKitchen

 

代码解读

这里为简单起见,只解读图一中 Bottle 的代码, 代码的作用,请仔细阅读注释

sampleBottle函数(创建Bottle,调用Texturize函数):

 

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

//通过载入brep文件,创建bottle,并贴纹理

void TexturesExt_Presentation::sampleBottle()

{  

//创建一个bottle

TopoDS_Shape aShape;

if (!loadShape(aShape, "bottle.brep"))

return;

 

// resize and move the shape to the center of the viewer  这块代码对纹理显示无贡献

gp_Trsf aTrsf1, aTrsf2;

aTrsf1.SetScale(gp_Pnt(0,0,0), /*0.8*/0.1);    //对 bottle 进行缩放

aTrsf2.SetTranslation(gp_Pnt(0,0,0),gp_Pnt(0,0,-20));

aTrsf1.Multiply(aTrsf2);

BRepBuilderAPI_Transform Transformer(aTrsf1);

Transformer.Perform(aShape);

aShape = Transformer.Shape();

 

        

TopTools_IndexedMapOfShape aFaces;

// 函数原型:static void TopExp::MapShapes(const TopoDS_Shape& S, const TopAbs_ShapeEnum T, TopTools_IndexedMapOfShape& M)

// 第二个参数: TopAbs_ShapeEnum 是一个枚举类型,读者需要自己去读一下

// Tool to explore a topological data structure. Stores in the map <M> all the sub-shapes of <S> of type <T>.

TopExp::MapShapes(aShape, TopAbs_FACE, aFaces);

 

 

//没有这几句代码 则只显示指定贴了纹理的那些FACE,不显示瓶子整体。但同样,这段对纹理的显示没有任何贡献。

//display original shape in shaded display mode

Handle_AIS_Shape aShapeIO = drawShape(aShape, Graphic3d_NOM_BRASS, Standard_False);

getAISContext()->SetDisplayMode(aShapeIO, AIS_Shaded, Standard_False);

// Set increased polygon offset for the main shape to avoid depth collision with textured faces

aShapeIO->SetPolygonOffsets(Aspect_POM_Fill, 1.5, 0.5);

DISP(aShapeIO);    // #define DISP(OBJ) getAISContext()->Display((OBJ), Standard_False)

 

 

//指定需要贴纹理的FACE,设置相关参数

Handle_AIS_TexturedShape aTFace1 = Texturize(aFaces(16), "carrelage1.gif", 1, 1, 3, 2);

DISP(aTFace1);

 

Handle_AIS_TexturedShape aTFace2 = Texturize(aFaces(21), "carrelage1.gif", 1, 1, 3, 2);

DISP(aTFace2);

 

//更新视图

getViewer()->Update();

}

 

Texturize函数(贴纹理):

 

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

Handle_AIS_TexturedShape TexturesExt_Presentation::Texturize(const TopoDS_Shape& aShape,

TCollection_AsciiString aTFileName,

Standard_Real toScaleU,

Standard_Real toScaleV,

Standard_Real toRepeatU,

Standard_Real toRepeatV,

Standard_Real originU,

Standard_Real originV)

{

//create a textured presentation object for aShape

//AIS_TexturedShape 是一个非常重要的类!下面是官方文档中的说明

//This class allows to map textures on shapes. Presentations modes AIS_WireFrame (0) and AIS_Shaded (1) behave in the same manner as in AIS_Shape

        //whilst new modes 2 (bounding box) and 3 (texture mapping) extends it functionality.

//The texture itself is parametrized in (0,1)x(0,1). Each face of a shape located in UV space is provided with these parameters:

//•Umin - starting position in U

//•Umax - ending position in U

//•Vmin - starting position in V

//•Vmax - ending position in V

//Each face is triangulated and a texel is assigned to each node. Facets are then filled using a linear interpolation of texture between each 'three texels'.

//User can act on:

//•the number of occurrences of the texture on the face

//•the position of the origin of the texture

//•the scale factor of the texture

Handle_AIS_TexturedShape aTShape = new AIS_TexturedShape(aShape);

 

TCollection_AsciiString TFileName;

 

 

//load texture from file if it is not an integer value

//integer value indicates a number of texture in predefined TexturesExt enumeration

CString initfile(((OCC_App*) AfxGetApp())->GetInitDataDir());

initfile += "\\Data\\";

if (!aTFileName.IsIntegerValue())

{

initfile += aTFileName.ToCString();

}

 

aTShape->SetTextureFileName((Standard_CString)(LPCTSTR)initfile);

 

// do other initialization of AIS_TexturedShape

aTShape->SetTextureMapOn();

aTShape->SetTextureScale(Standard_True, toScaleU, toScaleV);

aTShape->SetTextureRepeat(Standard_True, toRepeatU, toRepeatV);

aTShape->SetTextureOrigin(Standard_True, originU, originV);

 

aTShape->SetDisplayMode(3); // mode 3 is "textured" mode,参见上面AIS_TexturedShape类的解释

 

return aTShape;

}

至此,就可以实现上图中显示的Bottle效果。同学们可以自己创建一个简单的 box 来尝试一下,这里我给个简单的示例:

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

void CneedAVView::MakeBottle()

{

        TopoDS_Shape aRes = BRepPrimAPI_MakeBox(gp_Pnt(0,0,0),555,555,555).Shape();

        TopTools_IndexedMapOfShape aFaces;

TopExp::MapShapes(aRes, TopAbs_FACE, aFaces);

Handle(AIS_TexturedShape) aTFace1 = Texturize(aFaces(1), "./carrelage1.gif", 1, 1, 3, 2);

DISP(aTFace1);

 

Handle(AIS_TexturedShape) aTFace2 = Texturize(aFaces(2), "./carrelage1.gif", 1, 1, 3, 2);  //16 21 3 2

DISP(aTFace2);

 

Handle(AIS_TexturedShape) aTFace5 = Texturize(aFaces(5), "./carrelage1.gif", 1, 1, 3, 2);

DISP(aTFace5);

 

myView->Update();

}

 

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

Handle(AIS_TexturedShape) CneedAVView::Texturize(const TopoDS_Shape& aShape,

TCollection_AsciiString aTFileName,

Standard_Real toScaleU,

Standard_Real toScaleV,

Standard_Real toRepeatU,

Standard_Real toRepeatV,

Standard_Real originU,

Standard_Real originV)

{

// create a textured presentation object for aShape

Handle(AIS_TexturedShape) aTShape = new AIS_TexturedShape(aShape);

 

//此地纯属偷懒

CString temp("d://program files//opencascade-6.7.1//samples//mfc//standard//04_viewer3d//data//cookerplate.gif");

aTShape->SetTextureFileName((Standard_CString)(LPCTSTR)temp);

 

// do other initialization of AIS_TexturedShape

aTShape->SetTextureMapOn();

aTShape->SetTextureScale(Standard_True, toScaleU, toScaleV);

aTShape->SetTextureRepeat(Standard_True, toRepeatU, toRepeatV);

aTShape->SetTextureOrigin(Standard_True, originU, originV);

 

aTShape->SetDisplayMode(3); // mode 3 is "textured" mode

 

return aTShape;

}

也许你发现这样还是看不到显示的纹理!

后来发现,需要设置这样关键的一句

 

1

myView->SetSurfaceDetail(V3d_TEX_ALL);

 

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

函数原型:void V3d_View::SetSurfaceDetail(const V3d_TypeOfSurfaceDetail SurfaceDetail)

功    能:select the kind of rendering for texture mapping no texture mapping by default

 

 

其中 V3d_TypeOfSurfaceDetail 是一个枚举类

enum V3d_TypeOfSurfaceDetail

Modes of visualization for objects in a view.

·V3d_TEX_NONE: no texture mapping,

·V3d_TEX_ENVIRONMENT: environment mapping only,

·V3d_TEX_ALL: environment and texture mapping.

 

Enumerator:

·V3d_TEX_NONE

·V3d_TEX_ENVIRONMENT

·V3d_TEX_ALL

如官方文档中所述:

 

1

no texture mapping by default

所以我们要显示的把参数设置为:V3d_TEX_ALL

如此,你就可以看到自己贴的纹理了,效果图如下(因为我省略了一些函数所以这里只显示了贴纹理的面(见 sampleBottle 函数中所述)):

sample

 

至此,OpenCasCade的中的贴纹理就搞定了,想了解更多,请自行阅读官方示例。

 

感谢原作者的知识分享。

转自按地址:http://www.zyh1690.org/opencascade-texture/

  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值