7fd59977 |
1 | // File: AIS_TexturedShape.cdl |
2 | // Created: Mon Jul 2 11:32:59 2001 |
3 | // Author: Mathias BOSSHARD |
4 | // <mbd@pomalox.paris1.matra-dtv.fr> |
5 | // Copyright: Matra Datavision 2001 |
6 | // |
7 | // Modified: |
8 | // |
9 | // |
10 | // |
11 | //////////////////////////////////////////////////////////////////////// |
12 | |
13 | |
14 | #include <AIS_TexturedShape.ixx> |
15 | #include <Standard_ErrorHandler.hxx> |
16 | |
17 | #include <BRepTools.hxx> |
18 | #include <gp_Vec.hxx> |
19 | #include <Graphic3d_StructureManager.hxx> |
20 | #include <Graphic3d_Texture2Dmanual.hxx> |
21 | #include <Graphic3d_AspectFillArea3d.hxx> |
22 | #include <AIS_InteractiveContext.hxx> |
23 | #include <Prs3d_ShadingAspect.hxx> |
24 | #include <Prs3d_Root.hxx> |
25 | #include <PrsMgr_PresentationManager3d.hxx> |
26 | #include <Prs3d_Presentation.hxx> |
27 | #include <TopExp_Explorer.hxx> |
28 | #include <StdPrs_WFDeflectionShape.hxx> |
29 | #include <Graphic3d_Group.hxx> |
30 | #include <AIS_Drawer.hxx> |
31 | #include <StdPrs_WFShape.hxx> |
32 | #include <StdPrs_ShadedShape.hxx> |
33 | #include <StdPrs_ToolShadedShape.hxx> |
34 | #include <Precision.hxx> |
35 | #include <BRepMesh.hxx> |
36 | #include <Poly_Triangulation.hxx> |
37 | #include <Poly_Connect.hxx> |
38 | #include <Graphic3d_Array1OfVertexNT.hxx> |
39 | #include <Aspect_Array1OfEdge.hxx> |
40 | #include <TColgp_Array1OfDir.hxx> |
41 | #include <TColgp_Array1OfPnt2d.hxx> |
42 | |
43 | #define MAX2(X, Y) ( Abs(X) > Abs(Y)? Abs(X) : Abs(Y) ) |
44 | #define MAX3(X, Y, Z) ( MAX2 ( MAX2(X,Y) , Z) ) |
45 | |
46 | ////////////////////////////////////////////////////////////////////// |
47 | // CONSTRUCTOR / DESTRUCTOR |
48 | ////////////////////////////////////////////////////////////////////// |
49 | |
50 | //======================================================================= |
51 | //function : AIS_TexturedShape |
52 | //purpose : |
53 | //======================================================================= |
54 | |
55 | AIS_TexturedShape::AIS_TexturedShape(const TopoDS_Shape& ashape):AIS_Shape(ashape), |
56 | myPredefTexture(Graphic3d_NameOfTexture2D(0)), |
57 | myTextureFile(""), |
58 | DoRepeat(Standard_True), |
59 | myURepeat(1.0), |
60 | myVRepeat(1.0), |
61 | DoMapTexture(Standard_True), |
62 | DoSetTextureOrigin(Standard_True), |
63 | myUOrigin(0.0), |
64 | myVOrigin(0.0), |
65 | DoSetTextureScale(Standard_True), |
66 | myScaleU(1.0), |
67 | myScaleV(1.0), |
68 | DoShowTriangles(Standard_False), |
69 | myModulate(Standard_True) |
70 | { |
71 | } |
72 | |
73 | ////////////////////////////////////////////////////////////////////// |
74 | // TEXTURE MAPPING MANAGEMENT METHODS |
75 | ////////////////////////////////////////////////////////////////////// |
76 | |
77 | //======================================================================= |
78 | //function : SetTextureFileName |
79 | //purpose : |
80 | //======================================================================= |
81 | |
82 | void AIS_TexturedShape::SetTextureFileName(const TCollection_AsciiString& TextureFileName) |
83 | { |
84 | if (TextureFileName.IsIntegerValue()) |
85 | { |
86 | if(TextureFileName.IntegerValue()<Graphic3d_Texture2D::NumberOfTextures() && TextureFileName.IntegerValue()>=0) |
87 | myPredefTexture = (Graphic3d_NameOfTexture2D)(TextureFileName.IntegerValue()); |
88 | else |
89 | { |
90 | cout << "Texture "<<TextureFileName<<" doesn't exist \n"<< endl; |
91 | cout << "Using Texture 0 instead ...\n"<< endl; |
92 | myPredefTexture = (Graphic3d_NameOfTexture2D)(0); |
93 | } |
94 | myTextureFile = ""; |
95 | } |
96 | else |
97 | { |
98 | myTextureFile = TextureFileName; |
99 | myPredefTexture = (Graphic3d_NameOfTexture2D)(-1); |
100 | } |
101 | } |
102 | |
103 | //======================================================================= |
104 | //function : SetTextureRepeat |
105 | //purpose : |
106 | //======================================================================= |
107 | |
108 | void AIS_TexturedShape::SetTextureRepeat(const Standard_Boolean RepeatYN, |
109 | const Standard_Real URepeat, |
110 | const Standard_Real VRepeat) |
111 | { |
112 | DoRepeat = RepeatYN; |
113 | myURepeat = URepeat; |
114 | myVRepeat = VRepeat; |
115 | } |
116 | |
117 | //======================================================================= |
118 | //function : SetTextureMapOn |
119 | //purpose : |
120 | //======================================================================= |
121 | |
122 | void AIS_TexturedShape::SetTextureMapOn() |
123 | { |
124 | DoMapTexture = Standard_True; |
125 | } |
126 | |
127 | //======================================================================= |
128 | //function : SetTextureMapOff |
129 | //purpose : |
130 | //======================================================================= |
131 | |
132 | void AIS_TexturedShape::SetTextureMapOff() |
133 | { |
134 | DoMapTexture = Standard_False; |
135 | } |
136 | |
137 | //======================================================================= |
138 | //function : SetTextureOrigin |
139 | //purpose : |
140 | //======================================================================= |
141 | |
142 | void AIS_TexturedShape::SetTextureOrigin(const Standard_Boolean SetTextureOriginYN, const Standard_Real UOrigin, const Standard_Real VOrigin) |
143 | { |
144 | DoSetTextureOrigin = SetTextureOriginYN; |
145 | myUOrigin = UOrigin; |
146 | myVOrigin = VOrigin; |
147 | } |
148 | |
149 | //======================================================================= |
150 | //function : SetTextureScale |
151 | //purpose : |
152 | //======================================================================= |
153 | |
154 | void AIS_TexturedShape::SetTextureScale(const Standard_Boolean SetTextureScaleYN, const Standard_Real ScaleU, const Standard_Real ScaleV) |
155 | { |
156 | DoSetTextureScale = SetTextureScaleYN; |
157 | myScaleU = ScaleU; |
158 | myScaleV = ScaleV; |
159 | } |
160 | |
161 | //======================================================================= |
162 | //function : TriangleIsValid |
163 | //purpose : |
164 | //======================================================================= |
165 | |
166 | Standard_Boolean AIS_TexturedShape::TriangleIsValid(const gp_Pnt& P1, const gp_Pnt& P2, const gp_Pnt& P3) const |
167 | { |
168 | gp_Vec V1(P1,P2); // V1=(P1,P2) |
169 | gp_Vec V2(P2,P3); // V2=(P2,P3) |
170 | gp_Vec V3(P3,P1); // V3=(P3,P1) |
171 | |
172 | if ((V1.SquareMagnitude() > 1.e-10) && (V2.SquareMagnitude() > 1.e-10) && (V3.SquareMagnitude() > 1.e-10)) |
173 | { |
174 | V1.Cross(V2); // V1 = Normal |
175 | if (V1.SquareMagnitude() > 1.e-10) |
176 | return Standard_True; |
177 | else |
178 | return Standard_False; |
179 | } |
180 | else |
181 | return Standard_False; |
182 | |
183 | } |
184 | |
185 | //======================================================================= |
186 | //function : ShowTriangles |
187 | //purpose : |
188 | //======================================================================= |
189 | |
190 | void AIS_TexturedShape::ShowTriangles(const Standard_Boolean ShowTrianglesYN) |
191 | { |
192 | DoShowTriangles = ShowTrianglesYN; |
193 | } |
194 | |
195 | //======================================================================= |
196 | //function : EnableTextureModulate |
197 | //purpose : |
198 | //======================================================================= |
199 | |
200 | void AIS_TexturedShape::EnableTextureModulate() |
201 | { |
202 | myModulate = Standard_True; |
203 | } |
204 | |
205 | //======================================================================= |
206 | //function : DisableTextureModulate |
207 | //purpose : |
208 | //======================================================================= |
209 | |
210 | void AIS_TexturedShape::DisableTextureModulate() |
211 | { |
212 | myModulate = Standard_False; |
213 | } |
214 | |
215 | //======================================================================= |
216 | //function : UpdateAttributes |
217 | //purpose : |
218 | //======================================================================= |
219 | |
220 | void AIS_TexturedShape::UpdateAttributes() |
221 | { |
222 | Handle(Graphic3d_StructureManager) aStrucMana = GetContext()->MainPrsMgr()->StructureManager(); |
223 | myAspect = (new Prs3d_ShadingAspect())->Aspect(); |
224 | Handle(Prs3d_Presentation) aPrs = Presentation(); |
225 | if (!DoMapTexture) |
226 | { |
227 | myAspect->SetTextureMapOff(); |
228 | return; |
229 | } |
230 | |
231 | if(myPredefTexture!=-1) |
232 | mytexture = new Graphic3d_Texture2Dmanual(aStrucMana, myPredefTexture); |
233 | else |
234 | mytexture = new Graphic3d_Texture2Dmanual(aStrucMana, myTextureFile.ToCString()); |
235 | |
236 | myAspect->SetTextureMapOn(); |
237 | |
238 | myAspect->SetTextureMap(mytexture); |
239 | if (!mytexture->IsDone()) |
240 | { |
241 | cout << "An error occured while building texture \n" <<endl; |
242 | return; |
243 | } |
244 | |
245 | if (DoShowTriangles) |
246 | myAspect->SetEdgeOn(); |
247 | else |
248 | myAspect->SetEdgeOff(); |
249 | |
250 | Prs3d_Root::CurrentGroup(aPrs)->SetGroupPrimitivesAspect(myAspect); |
251 | } |
252 | |
253 | //======================================================================= |
254 | //function : Compute |
255 | //purpose : |
256 | //======================================================================= |
257 | |
258 | void AIS_TexturedShape::Compute(const Handle(PrsMgr_PresentationManager3d)& /*aPresentationManager*/, |
259 | const Handle(Prs3d_Presentation)& aPrs, |
260 | const Standard_Integer aMode) |
261 | { |
262 | aPrs->Clear(); |
263 | |
264 | if(myshape.IsNull()) return; |
265 | |
266 | Standard_Integer TheType; |
267 | TheType = (Standard_Integer) myshape.ShapeType(); |
268 | if(TheType>4 && TheType<8) |
269 | { |
270 | aPrs->SetVisual(Graphic3d_TOS_ALL); |
271 | aPrs->SetDisplayPriority(TheType+2); |
272 | } |
273 | |
274 | if (myshape.ShapeType() == TopAbs_COMPOUND) |
275 | { |
276 | TopExp_Explorer anExplor (myshape, TopAbs_VERTEX); |
277 | if (!anExplor.More()) {return;} |
278 | } |
279 | |
280 | if (IsInfinite()) |
281 | aPrs->SetInfiniteState(Standard_True); |
282 | |
283 | switch (aMode) |
284 | { |
285 | |
286 | case 0: // Wireframe |
287 | StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer); |
288 | break; |
289 | |
290 | case 1: // Shading) |
291 | { |
292 | Standard_Real prevangle ; |
293 | Standard_Real newangle ; |
294 | Standard_Real prevcoeff ; |
295 | Standard_Real newcoeff ; |
296 | |
297 | if (OwnDeviationAngle(newangle,prevangle) || OwnDeviationCoefficient(newcoeff,prevcoeff)) |
298 | if (Abs (newangle - prevangle) > Precision::Angular() || Abs (newcoeff - prevcoeff) > Precision::Confusion() ) |
299 | { |
300 | BRepTools::Clean(myshape); |
301 | } |
302 | if ((Standard_Integer) myshape.ShapeType()>4) |
303 | StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer); |
304 | else |
305 | { |
306 | myDrawer->SetShadingAspectGlobal(Standard_False); |
307 | if (IsInfinite()) |
308 | StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer); |
309 | else |
310 | { |
311 | try |
312 | { |
313 | OCC_CATCH_SIGNALS |
314 | StdPrs_ShadedShape::Add(aPrs,myshape,myDrawer); |
315 | } |
316 | catch (Standard_Failure) |
317 | { |
318 | cout <<"AIS_TexturedShape::Compute() in ShadingMode failed \n" <<endl; |
319 | StdPrs_WFShape::Add(aPrs,myshape,myDrawer); |
320 | } |
321 | } |
322 | } |
323 | break; |
324 | } |
325 | |
326 | case 2: // Bounding box |
327 | { |
328 | if (IsInfinite()) |
329 | { |
330 | StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer); |
331 | } |
332 | else |
333 | { |
334 | AIS_Shape::DisplayBox(aPrs,BoundingBox(),myDrawer); |
335 | } |
336 | break; |
337 | } |
338 | |
339 | case 3: // texture mapping on triangulation |
340 | { |
341 | BRepTools::Clean(myshape); |
342 | BRepTools::Update(myshape); |
343 | |
344 | Handle(Graphic3d_StructureManager) aStrucMana = GetContext()->MainPrsMgr()->StructureManager(); |
ab943560 |
345 | { |
346 | Handle(Prs3d_ShadingAspect) aPrs3d_ShadingAspect = new Prs3d_ShadingAspect; |
347 | myAspect = aPrs3d_ShadingAspect->Aspect(); |
348 | } |
7fd59977 |
349 | if (!DoMapTexture) |
350 | { |
351 | myAspect->SetTextureMapOff(); |
352 | return; |
353 | } |
354 | myAspect->SetTextureMapOn(); |
355 | |
356 | if(myPredefTexture!=-1) |
357 | mytexture = new Graphic3d_Texture2Dmanual(aStrucMana, myPredefTexture); |
358 | else |
359 | mytexture = new Graphic3d_Texture2Dmanual(aStrucMana, myTextureFile.ToCString()); |
360 | |
361 | if (!mytexture->IsDone()) |
362 | { |
363 | cout <<"An error occured while building texture \n" <<endl; |
364 | return; |
365 | } |
366 | if (myModulate) |
367 | mytexture->EnableModulate(); |
368 | else |
369 | mytexture->DisableModulate(); |
370 | |
371 | myAspect->SetTextureMap(mytexture); |
372 | if (DoShowTriangles) |
373 | myAspect->SetEdgeOn(); |
374 | else |
375 | myAspect->SetEdgeOff(); |
376 | |
377 | if (DoRepeat) |
378 | mytexture->EnableRepeat(); |
379 | else |
380 | mytexture->DisableRepeat(); |
381 | |
382 | myDeflection = AIS_Shape::GetDeflection(myshape,myDrawer); |
383 | BRepMesh::Mesh(myshape,myDeflection); |
384 | // Adds a triangulation of the shape myshape to its topological data structure. |
385 | // This triangulation is computed with the deflection myDeflection. |
386 | |
387 | #ifdef DEBUG |
388 | cout <<"Deflection = " << myDeflection << "\n" << endl; |
389 | #endif |
390 | |
391 | StdPrs_ToolShadedShape SST; |
392 | |
393 | Standard_Integer NumFace; |
394 | TopExp_Explorer ExpFace; |
395 | |
396 | for( NumFace=0,ExpFace.Init(myshape,TopAbs_FACE); ExpFace.More(); ExpFace.Next(),NumFace++ ) |
397 | { |
398 | TopoDS_Face myFace = TopoDS::Face(ExpFace.Current()); |
399 | TopLoc_Location aLocation = myFace.Location(); |
400 | |
401 | #ifdef DEBUG |
402 | cout << "J\'explore actuellement la face " << NumFace << "\n" << endl; |
403 | #endif |
404 | Handle(Poly_Triangulation) myT = BRep_Tool::Triangulation(myFace, aLocation); |
405 | // Returns the Triangulation of the face. It is a null handle if there is no triangulation. |
406 | |
407 | if (myT.IsNull()) |
408 | { |
409 | #ifdef DEBUG |
410 | cout << "Triangulation of the face "<< i <<" is null \n"<< endl; |
411 | #endif |
412 | return; |
413 | } |
414 | Poly_Connect pc(myT); |
415 | const TColgp_Array1OfPnt& Nodes = myT->Nodes(); |
416 | const TColgp_Array1OfPnt2d& UVNodes = myT->UVNodes(); |
417 | const Poly_Array1OfTriangle& triangles = myT->Triangles(); |
418 | TColgp_Array1OfDir myNormal(Nodes.Lower(), Nodes.Upper()); |
419 | |
420 | SST.Normal(myFace, pc, myNormal); |
421 | BRepTools::UVBounds(myFace,Umin, Umax, Vmin, Vmax); |
422 | dUmax = (Umax - Umin); |
423 | dVmax = (Vmax - Vmin); |
424 | Handle(Graphic3d_Group) mygroup = Prs3d_Root::CurrentGroup(aPrs); |
425 | |
81bba717 |
426 | Standard_Integer nnn = myT->NbTriangles(); // nnn : number of triangles |
427 | Standard_Integer nt, n1, n2, n3 = 0; // nt : current triangle |
428 | // ni : top i of the current triangle |
7fd59977 |
429 | for (nt = 1; nt <= nnn; nt++) |
430 | { |
431 | #ifdef DEBUG |
432 | cout << "On traite actuellement le triangle : "<< nt <<"\n"; |
433 | #endif |
81bba717 |
434 | if (SST.Orientation(myFace) == TopAbs_REVERSED) // if the face is "reversed" |
435 | triangles(nt).Get(n1,n3,n2); // the triangle is n1,n3,n2 |
7fd59977 |
436 | else |
81bba717 |
437 | triangles(nt).Get(n1,n2,n3); // the triangle is n1,n2,n3 |
7fd59977 |
438 | |
439 | if (TriangleIsValid (Nodes(n1),Nodes(n2),Nodes(n3)) ) |
81bba717 |
440 | { // Associates vertexNT to each node |
7fd59977 |
441 | Graphic3d_Array1OfVertexNT Points(1,3); |
442 | Aspect_Array1OfEdge aretes(1,3); |
443 | |
444 | mygroup->BeginPrimitives(); |
445 | { |
446 | gp_Pnt p = Nodes(n1).Transformed(aLocation.Transformation()); |
447 | gp_Pnt q = Nodes(n2).Transformed(aLocation.Transformation()); |
448 | gp_Pnt r = Nodes(n3).Transformed(aLocation.Transformation()); |
449 | |
450 | Points(1).SetCoord(p.X(), p.Y(), p.Z()); |
451 | Points(2).SetCoord(q.X(), q.Y(), q.Z()); |
452 | Points(3).SetCoord(r.X(), r.Y(), r.Z()); |
453 | |
454 | Points(1).SetNormal(myNormal(n1).X(), myNormal(n1).Y(), myNormal(n1).Z()); |
455 | Points(2).SetNormal(myNormal(n2).X(), myNormal(n2).Y(), myNormal(n2).Z()); |
456 | Points(3).SetNormal(myNormal(n3).X(), myNormal(n3).Y(), myNormal(n3).Z()); |
457 | |
458 | Points(1).SetTextureCoordinate((-myUOrigin+(myURepeat*(UVNodes(n1).X()-Umin))/dUmax)/myScaleU, |
459 | (-myVOrigin+(myVRepeat*(UVNodes(n1).Y()-Vmin))/dVmax)/myScaleV); |
460 | Points(2).SetTextureCoordinate((-myUOrigin+(myURepeat*(UVNodes(n2).X()-Umin))/dUmax)/myScaleU, |
461 | (-myVOrigin+(myVRepeat*(UVNodes(n2).Y()-Vmin))/dVmax)/myScaleV); |
462 | Points(3).SetTextureCoordinate((-myUOrigin+(myURepeat*(UVNodes(n3).X()-Umin))/dUmax)/myScaleU, |
463 | (-myVOrigin+(myVRepeat*(UVNodes(n3).Y()-Vmin))/dVmax)/myScaleV); |
464 | |
465 | aretes(1).SetValues(1, 2, Aspect_TOE_INVISIBLE); |
466 | aretes(2).SetValues(2, 3, Aspect_TOE_INVISIBLE); |
467 | aretes(3).SetValues(3, 1, Aspect_TOE_INVISIBLE); |
468 | } |
469 | mygroup->EndPrimitives(); |
470 | mygroup->TriangleSet(Points, aretes, Standard_True); |
471 | |
472 | } // end of "if the triangle is valid |
473 | } // end of the "parcours" of the triangles |
474 | mygroup->SetGroupPrimitivesAspect(myAspect); |
475 | }// end of the exploration of the shape in faces |
476 | break; |
477 | }// end case 3 |
478 | |
479 | } // end switch |
480 | // aPrs->ReCompute(); // for hidden line recomputation if necessary... |
481 | } |
482 | |
483 | |
484 | |
485 | |
486 | |
487 | ///////////////////////////////////////////////////////// |
488 | // QUERY METHODS |
489 | ///////////////////////////////////////////////////////// |
490 | |
491 | |
492 | |
493 | Standard_Boolean AIS_TexturedShape::TextureMapState() const |
494 | { |
495 | return DoMapTexture; |
496 | } |
497 | |
498 | Standard_Real AIS_TexturedShape::URepeat() const |
499 | { |
500 | return myURepeat; |
501 | } |
502 | |
503 | Standard_Boolean AIS_TexturedShape::TextureRepeat() const |
504 | { |
505 | return DoRepeat; |
506 | } |
507 | |
508 | Standard_Real AIS_TexturedShape::Deflection() const |
509 | { |
510 | return myDeflection; |
511 | } |
512 | |
513 | Standard_CString AIS_TexturedShape::TextureFile() const |
514 | { |
515 | return myTextureFile.ToCString(); |
516 | } |
517 | |
518 | Standard_Real AIS_TexturedShape::VRepeat() const |
519 | { |
520 | return myVRepeat; |
521 | } |
522 | Standard_Boolean AIS_TexturedShape::ShowTriangles() const |
523 | { |
524 | return DoShowTriangles; |
525 | } |
526 | Standard_Real AIS_TexturedShape::TextureUOrigin() const |
527 | { |
528 | return myUOrigin; |
529 | } |
530 | Standard_Real AIS_TexturedShape::TextureVOrigin() const |
531 | { |
532 | return myVOrigin; |
533 | } |
534 | Standard_Real AIS_TexturedShape::TextureScaleU() const |
535 | { |
536 | return myScaleU; |
537 | } |
538 | Standard_Real AIS_TexturedShape::TextureScaleV() const |
539 | { |
540 | return myScaleV; |
541 | } |
542 | Standard_Boolean AIS_TexturedShape::TextureScale() const |
543 | { |
544 | return DoSetTextureScale; |
545 | } |
546 | Standard_Boolean AIS_TexturedShape::TextureOrigin() const |
547 | { |
548 | return DoSetTextureOrigin; |
549 | } |
550 | Standard_Boolean AIS_TexturedShape::TextureModulate() const |
551 | { |
552 | return myModulate; |
553 | } |