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