0031431: Visualization, PrsMgr_PresentableObject - simplify HLR computing interface
[occt.git] / samples / mfc / standard / Common / User_Cylinder.cxx
1 #include <stdafx.h>
2
3 #include <User_Cylinder.hxx>
4
5 // Implementation of Handle and type mgt
6 //
7
8 IMPLEMENT_STANDARD_RTTIEXT(User_Cylinder,AIS_InteractiveObject)
9
10 #include "ColoredMeshDlg.h"
11
12 #include <Graphic3d_ArrayOfTriangles.hxx>
13 #include <Graphic3d_StructureManager.hxx>
14 #include <PrsMgr_PresentationManager3d.hxx>
15 #include <StdPrs_ToolTriangulatedShape.hxx>
16 #include <Poly_Connect.hxx>
17 #include <TColgp_Array1OfPnt.hxx>
18 #include <Poly_Triangulation.hxx>
19 #include <TColgp_Array1OfDir.hxx>
20 #include <GProp_PGProps.hxx>
21 #include <Quantity_Color.hxx>
22 #include <BRepMesh_IncrementalMesh.hxx>
23 #include <Prs3d.hxx>
24
25 #include <AIS_GraphicTool.hxx>
26
27 // Constructors implementation
28 //
29
30 User_Cylinder::User_Cylinder(const Standard_Real R, const Standard_Real H) :
31 AIS_InteractiveObject(PrsMgr_TOP_ProjectorDependant)
32 {
33   BRepPrimAPI_MakeCylinder S(R,H);
34   myShape = S.Shape();
35   SetHilightMode(0);
36   myDrawer->SetShadingAspect(new Prs3d_ShadingAspect());
37   myColor = Quantity_NOC_GRAY;
38 }
39
40 User_Cylinder::User_Cylinder(const gp_Ax2 CylAx2, const Standard_Real R, const Standard_Real H) :
41 AIS_InteractiveObject(PrsMgr_TOP_ProjectorDependant)
42
43 {
44   BRepPrimAPI_MakeCylinder S(CylAx2,R,H);
45   BRepBuilderAPI_NurbsConvert aNurbsConvert(S.Shape());
46   myShape = aNurbsConvert.Shape();
47   SetHilightMode(0);
48   myDrawer->SetShadingAspect(new Prs3d_ShadingAspect());
49   myColor = Quantity_NOC_KHAKI4;
50 }
51
52 void User_Cylinder::Compute(const Handle(PrsMgr_PresentationManager3d)& /*aPresentationManager*/,
53                             const Handle(Prs3d_Presentation)& aPresentation,
54                             const Standard_Integer aMode ) 
55 {
56   switch (aMode) {
57 case AIS_WireFrame:
58   {
59     StdPrs_WFShape::Add(aPresentation,myShape, myDrawer );
60     break;
61   }
62 case AIS_Shaded:
63   {
64     Standard_Real aTransparency = Transparency();
65     Graphic3d_NameOfMaterial aMaterial = Material();
66     myDrawer->ShadingAspect()->SetMaterial(aMaterial);
67     myDrawer->ShadingAspect()->SetColor(myColor);
68     myDrawer->ShadingAspect()->SetTransparency (aTransparency);
69     StdPrs_ShadedShape::Add(aPresentation,myShape, myDrawer);
70     break;
71   }
72 case 6: //color
73   {
74     BRepTools::Clean(myShape);
75     BRepTools::Update(myShape);
76
77     Handle(Graphic3d_StructureManager) aStrucMana = GetContext()->MainPrsMgr()->StructureManager();
78
79     Handle(Graphic3d_Group) mygroup = Prs3d_Root::CurrentGroup(aPresentation);
80     myAspect = (new Prs3d_ShadingAspect())->Aspect();
81     Graphic3d_MaterialAspect material = myAspect->FrontMaterial();
82     material.SetAmbientColor (Quantity_NOC_BLACK);
83     material.SetDiffuseColor (Quantity_NOC_BLACK);
84     material.SetSpecularColor(Quantity_NOC_BLACK);
85     material.SetEmissiveColor(Quantity_NOC_BLACK);
86     myAspect->SetFrontMaterial(material);
87
88     mygroup->SetPrimitivesAspect(myAspect);
89     myAspect->SetEdgeOn();
90
91     myDeflection = Prs3d::GetDeflection(myShape,myDrawer);
92     BRepMesh_IncrementalMesh(myShape,myDeflection);
93
94     myX1OnOff = Standard_False;
95     myXBlueOnOff = Standard_False;
96     myXGreenOnOff =Standard_False;
97     myXRedOnOff = Standard_False;
98     myY1OnOff = Standard_False;
99     myYBlueOnOff = Standard_False;
100     myYGreenOnOff = Standard_False;
101     myYRedOnOff = Standard_False;
102     myZ1OnOff = Standard_False;
103     myZBlueOnOff =Standard_False;
104     myZGreenOnOff = Standard_False;
105     myZRedOnOff = Standard_False;
106
107     CColoredMeshDlg Dlg(NULL);
108     Dlg.DoModal();
109
110     myX1OnOff = Dlg.X1OnOff;
111
112     myXBlueOnOff  = Dlg.m_CheckXBlueOnOff  != 0;
113     myXGreenOnOff = Dlg.m_CheckXGreenOnOff != 0;
114     myXRedOnOff   = Dlg.m_CheckXRedOnOff   != 0;
115
116     myY1OnOff = Dlg.Y1OnOff;
117
118     myYBlueOnOff  = Dlg.m_CheckYBlueOnOff  != 0;
119     myYGreenOnOff = Dlg.m_CheckYGreenOnOff != 0;
120     myYRedOnOff   = Dlg.m_CheckYRedOnOff   != 0;
121
122     myZ1OnOff = Dlg.Z1OnOff;
123
124     myZBlueOnOff  = Dlg.m_CheckZBlueOnOff  != 0;
125     myZGreenOnOff = Dlg.m_CheckZGreenOnOff != 0;
126     myZRedOnOff   = Dlg.m_CheckZRedOnOff   != 0;
127
128     // Adds a triangulation of the shape myShape to its topological data structure.
129     // This triangulation is computed with the deflection myDeflection.
130
131 #ifdef DEBUG
132     std::cout <<"Deflection = " << myDeflection << "\n" << std::endl;
133 #endif
134
135     Standard_Integer NumFace;
136     TopExp_Explorer ExpFace;
137
138     //khr -->
139
140     gp_Pnt H (0,0,0);
141     gp_Pnt B (0,0,1000000000);
142     for( NumFace=0,ExpFace.Init(myShape,TopAbs_FACE); ExpFace.More(); ExpFace.Next(),NumFace++ )
143     {
144       TopoDS_Face myFace = TopoDS::Face(ExpFace.Current());
145       TopLoc_Location myLocation = myFace.Location();
146
147 #ifdef DEBUG
148       std::cout << "J\'explore actuellement la face " << NumFace << "\n" << std::endl;
149 #endif
150       Handle(Poly_Triangulation) myT = BRep_Tool::Triangulation(myFace, myLocation);
151       // Returns the Triangulation of the face. It is a null handle if there is no triangulation.
152
153       if (myT.IsNull())
154       {
155 #ifdef DEBUG
156         // std::cout << "Triangulation of the face "<< i <<" is null \n"<< std::endl;
157 #endif
158         return;
159       }
160
161       const TColgp_Array1OfPnt& Nodes= myT->Nodes();
162
163       const Poly_Array1OfTriangle& triangles = myT->Triangles();
164
165       Standard_Integer nnn = myT->NbTriangles(); // nnn : nombre de triangles
166       Standard_Integer nt, n1, n2, n3 = 0;// nt : triangle courant
167       // ni : sommet i du triangle courant
168       //recherche du pt "haut" et du pt "bas
169       for (nt = 1; nt <= nnn; nt++)
170       {
171         // triangles(nt).Get(n1,n2,n3); // le triangle est n1,n2,n3
172
173         if (myFace.Orientation() == TopAbs_REVERSED) // si la face est "reversed"
174           triangles(nt).Get(n1,n3,n2); // le triangle est n1,n3,n2
175         else
176           triangles(nt).Get(n1,n2,n3); // le triangle est n1,n2,n3
177
178         if (TriangleIsValid (Nodes(n1),Nodes(n2),Nodes(n3)) )
179         { // Associates a vertexNT to each node
180           gp_Pnt p = Nodes(n1).Transformed(myLocation.Transformation());
181           gp_Pnt q = Nodes(n2).Transformed(myLocation.Transformation());
182           gp_Pnt r = Nodes(n3).Transformed(myLocation.Transformation());
183
184           if (p.Z() > H.Z()) H=p;
185           if (q.Z() > H.Z()) H=q;
186           if (r.Z() > H.Z()) H=r;
187           if (p.Z() < B.Z()) B=p;
188           if (q.Z() < B.Z()) B=q;
189           if (r.Z() < B.Z()) B=r;
190         }
191       }
192     }
193
194     //khr <--
195
196
197     for( NumFace=0,ExpFace.Init(myShape,TopAbs_FACE); ExpFace.More(); ExpFace.Next(),NumFace++ )
198     {
199       TopoDS_Face myFace = TopoDS::Face(ExpFace.Current());
200       TopLoc_Location myLocation = myFace.Location();
201
202 #ifdef DEBUG
203       std::cout << "J\'explore actuellement la face " << NumFace << "\n" << std::endl;
204 #endif
205       Handle(Poly_Triangulation) myT = BRep_Tool::Triangulation(myFace, myLocation);
206       // Returns the Triangulation of the face. It is a null handle if there is no triangulation.
207
208       if (myT.IsNull())
209       {
210 #ifdef DEBUG
211         //std::cout << "Triangulation of the face "<< i <<" is null \n"<< std::endl;
212 #endif
213         return;
214       }
215       Poly_Connect pc(myT);
216       const TColgp_Array1OfPnt& Nodes= myT->Nodes();
217       BAR = GProp_PGProps::Barycentre(Nodes);
218
219
220       //const TColgp_Array1OfPnt2d& UVNodes = myT->UVNodes();
221       const Poly_Array1OfTriangle& triangles = myT->Triangles();
222       TColgp_Array1OfDir myNormal(Nodes.Lower(), Nodes.Upper());
223
224       StdPrs_ToolTriangulatedShape::Normal(myFace, pc, myNormal);
225       BRepTools::UVBounds(myFace,Umin, Umax, Vmin, Vmax);
226       dUmax = (Umax - Umin);
227       dVmax = (Vmax - Vmin);
228
229       Standard_Integer nnn = myT->NbTriangles(); // nnn : nombre de triangles
230       Standard_Integer nt, n1, n2, n3 = 0;// nt : triangle courant
231       // ni : sommet i du triangle courant
232
233       //recherche du pt "haut" et du pt "bas
234       // gp_Pnt H (0,0,0);
235       // gp_Pnt B (0,0,1000000000);
236
237       for (nt = 1; nt <= nnn; nt++)
238       {
239         // triangles(nt).Get(n1,n2,n3); // le triangle est n1,n2,n3
240         if (myFace.Orientation() == TopAbs_REVERSED) // si la face est "reversed"
241           triangles(nt).Get(n1,n3,n2); // le triangle est n1,n3,n2
242         else
243           triangles(nt).Get(n1,n2,n3); // le triangle est n1,n2,n3
244
245         if (TriangleIsValid (Nodes(n1),Nodes(n2),Nodes(n3)) )
246         { // Associates a vertexNT to each node
247           gp_Pnt p = Nodes(n1).Transformed(myLocation.Transformation());
248           gp_Pnt q = Nodes(n2).Transformed(myLocation.Transformation());
249           gp_Pnt r = Nodes(n3).Transformed(myLocation.Transformation());
250         }
251       }
252
253       Handle(Graphic3d_ArrayOfTriangles) aOP = new Graphic3d_ArrayOfTriangles(3 * nnn, 0, Standard_True, Standard_True);
254
255       for (nt = 1; nt <= nnn; nt++)
256       {
257 #ifdef DEBUG
258         std::cout << "On traite actuellement le triangle : "<< nt <<"\n";
259 #endif
260         if (myFace.Orientation() == TopAbs_REVERSED) // si la face est "reversed"
261           triangles(nt).Get(n1,n3,n2); // le triangle est n1,n3,n2
262         else
263           triangles(nt).Get(n1,n2,n3); // le triangle est n1,n2,n3
264
265         if (TriangleIsValid (Nodes(n1),Nodes(n2),Nodes(n3)) )
266         { // Associates a vertexNT to each node
267
268           TColgp_Array1OfPnt Points(1,3);
269
270           gp_Pnt p = Nodes(n1).Transformed(myLocation.Transformation());
271           gp_Pnt q = Nodes(n2).Transformed(myLocation.Transformation());
272           gp_Pnt r = Nodes(n3).Transformed(myLocation.Transformation());
273
274           Points(1).SetCoord(p.X(), p.Y(), p.Z());
275           Points(2).SetCoord(q.X(), q.Y(), q.Z());
276           Points(3).SetCoord(r.X(), r.Y(), r.Z());
277
278           aOP->AddVertex(Points(1), myNormal(n1), Color(p,B.Z(),H.Z(),Dlg.Colorization));
279           aOP->AddVertex(Points(2), myNormal(n2), Color(q,B.Z(),H.Z(),Dlg.Colorization));
280           aOP->AddVertex(Points(3), myNormal(n3), Color(r,B.Z(),H.Z(),Dlg.Colorization));
281         } // end of "if the triangle is valid
282       } // end of the "parcours" of the triangles
283
284       Prs3d_Root::CurrentGroup (aPresentation)->AddPrimitiveArray (aOP);
285
286       mygroup->SetGroupPrimitivesAspect(myAspect);
287     }// end of the exploration of the shape in faces
288
289     break;
290   }
291   }
292 }
293
294 void User_Cylinder::computeHLR (const Handle(Graphic3d_Camera)& aProjector,
295                                 const Handle(Geom_Transformation)& ,
296                                 const Handle(Prs3d_Presentation)& aPresentation)
297 {
298   Handle (Prs3d_Drawer) aDefDrawer = GetContext()->DefaultDrawer();
299   if (aDefDrawer->DrawHiddenLine())
300     myDrawer->EnableDrawHiddenLine();
301   else
302     myDrawer->DisableDrawHiddenLine();
303   StdPrs_HLRPolyShape aTool;
304   aTool.ComputeHLR (aPresentation,myShape,myDrawer,aProjector);
305 }
306
307 void User_Cylinder::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
308                                     const Standard_Integer aMode)
309 {
310   switch(aMode)
311   {
312   case 0:
313     StdSelect_BRepSelectionTool::Load(aSelection,this,myShape,TopAbs_SHAPE, 0.01, 0.1);
314     break;
315   case 4:
316     StdSelect_BRepSelectionTool::Load(aSelection,this,myShape,TopAbs_FACE, 0.01, 0.1);
317     break;
318   }
319 }
320
321 Standard_Integer User_Cylinder::NbPossibleSelection() const
322 {
323   return 2;
324 }
325
326 Standard_Boolean User_Cylinder::AcceptShapeDecomposition() const
327 {
328   return Standard_True;
329 }
330
331 Standard_Boolean User_Cylinder::TriangleIsValid(const gp_Pnt& P1, const gp_Pnt& P2, const gp_Pnt& P3) const
332
333   gp_Vec V1(P1,P2);// V1=(P1,P2)
334   gp_Vec V2(P2,P3);// V2=(P2,P3)
335   gp_Vec V3(P3,P1);// V3=(P3,P1)
336
337   if ((V1.SquareMagnitude() > 1.e-10) && (V2.SquareMagnitude() > 1.e-10) && (V3.SquareMagnitude() > 1.e-10))
338   {
339     V1.Cross(V2);// V1 = Normal 
340     if (V1.SquareMagnitude() > 1.e-10)
341       return Standard_True;
342     else
343       return Standard_False;
344   }
345   else
346     return Standard_False;
347 }
348
349 Quantity_Color User_Cylinder::Color(gp_Pnt& thePoint,Standard_Real AltMin,Standard_Real AltMax,
350                                     const Standard_Integer ColorizationMode) 
351 {
352   red =1; //initializing colors parameters
353   green=1;
354   blue =1;
355   switch ( ColorizationMode)
356   {
357   case 0 : //normal, vert/maron
358     {
359       Standard_Real Alt= thePoint.Z();
360
361       Standard_Real AltDelta;
362
363       AltDelta = AltMax-AltMin;
364
365       red = 0.5- ((0.5*(AltMax-Alt))/(AltDelta));
366       //Standard_Real A = 7*Alt-7*AltMin;
367       green = (3*AltMax-AltMin)/(3*AltMax-AltMin+(7*Alt-7*AltMin));
368       blue = 0 ;
369
370       Quantity_Color color;
371       color.SetValues(red,green,blue, Quantity_TOC_RGB);
372       return color;
373       break;
374     }//end case 0
375
376   case 1 : //mer-neige
377     {
378       Standard_Real Alt= thePoint.Z();
379
380       Standard_Real b =AltMax-AltMin;
381       Standard_Real a= AltMax-thePoint.Z();
382
383       red =1;
384       green=1;
385       blue =1;
386       if (0<a && a <= (b/5))
387       {
388         red = 1;
389         green = 1;
390         blue = 1;
391       }
392       else if ((b/5)<a && a <= (2*b/5))
393       {
394         red = .55;
395         green = 0.3;
396         blue = 0;
397       }
398       else if ((2*b/5)<a && a <= (18*b/20))
399       {
400         green =1/(((7/(3*AltMax-AltMin))*Alt)+(1-(7*AltMin/(3*AltMax-AltMin))));
401         red = 1/(((1000/(AltMax-AltMin))*Alt)+1000*(1-(AltMin/(AltMax-AltMin))));
402         blue = 0;
403       }
404       else if ((18*b/20)<a && a <= (18.5*b/20))
405       {
406         red = 0.75;
407         green = 0.66;
408         blue = 0;
409       }
410
411       else if ((18.5*b/20)<a && a <= b)
412       {
413         red = 0.25;
414         green = .66;
415         blue = 1;
416       }
417       Quantity_Color color;
418       color.SetValues(red,green,blue, Quantity_TOC_RGB);
419       return color;
420       break;
421     }//end case 1
422
423   case 2 :
424     {
425       gp_Pnt P (85.,0.,-105.);
426       gp_Vec TheVect ( P, thePoint);
427       Standard_Real CoordX;
428       Standard_Real CoordY;
429       Standard_Real CoordZ;
430
431       CoordX = TheVect.X();
432       CoordY = TheVect.Y();
433       CoordZ = TheVect.Z();
434
435       Standard_Real Distance = BAR.Distance ( P);
436
437       Standard_Real a =fabs(CoordX);
438       Standard_Real b =fabs(CoordY);
439       Standard_Real c =fabs(CoordZ);
440
441       Standard_Real xx = a / Max(Distance,a); //(Max (Distance, Maxi));
442       Standard_Real yy = b / Max(Distance,b); //(Max (Distance, Maxi));
443       Standard_Real zz = c / Max(Distance,c); //(Max (Distance, Maxi));
444
445
446       if (myXRedOnOff)
447         red = xx;
448       else if (myXGreenOnOff)
449         green =xx;
450       else if (myXBlueOnOff)
451         blue=xx;
452
453       if (myYRedOnOff)
454         red = yy;
455       else if (myYGreenOnOff)
456         green = yy;
457       else if (myYBlueOnOff)
458         blue = yy;
459
460       if (myZRedOnOff)
461         red = zz;
462       else if (myZGreenOnOff)
463         green = zz;
464       else if (myZBlueOnOff)
465         blue = zz;
466       Quantity_Color color;
467       color.SetValues(red,green,blue, Quantity_TOC_RGB);
468       return color;
469       break;
470     }//end case 2
471   }//end switch
472
473   Quantity_Color c;
474   return c;
475 }
476
477 void User_Cylinder::SetColor(const Quantity_Color &aColor)
478 {
479   AIS_InteractiveObject::SetColor(aColor);
480   myColor = aColor;
481 }