Commit | Line | Data |
---|---|---|
7fd59977 | 1 | // File: Prs3d_ShadedShape.gxx |
2 | // Created: Thu Sep 23 18:47:22 1993 | |
3 | // Author: Jean-Louis FRENKEL | |
4 | // <jlf@stylox> | |
5 | ||
6 | //#define BUC60488//GG_081199 Enable the SuppressBackface() ShadingAspect attribute | |
7 | ||
8 | #define G005 //ATS,GG 04/01/01 Use ArrayOfPrimitives instead Sets of primitives | |
9 | // for performance improvment | |
10 | ||
11 | #include <Graphic3d_Vertex.hxx> | |
12 | #include <Graphic3d_VertexN.hxx> | |
13 | #include <Graphic3d_Array1OfVertexN.hxx> | |
14 | #include <Graphic3d_Array1OfVertex.hxx> | |
15 | #include <Aspect_Edge.hxx> | |
16 | #include <Aspect_Array1OfEdge.hxx> | |
17 | #include <gp_Pnt.hxx> | |
18 | #include <gp_Dir.hxx> | |
19 | #include <Prs3d_ShadingAspect.hxx> | |
20 | #include <Graphic3d_Group.hxx> | |
21 | #include <Aspect_TypeOfEdge.hxx> | |
22 | #include <Bnd_Box.hxx> | |
23 | #include <Graphic3d_AspectFillArea3d.hxx> | |
24 | #include <BRepTools.hxx> | |
25 | #include <BRep_Tool.hxx> | |
26 | #include <BRep_Builder.hxx> | |
27 | #include <TopoDS_Compound.hxx> | |
28 | #include <Poly_Triangulation.hxx> | |
29 | #include <TColgp_HArray1OfPnt.hxx> | |
30 | #include <TColgp_Array1OfPnt.hxx> | |
31 | #include <TColgp_Array1OfPnt2d.hxx> | |
32 | #include <TColgp_Array1OfDir.hxx> | |
33 | #include <Poly_Connect.hxx> | |
34 | #include <TopAbs_Orientation.hxx> | |
35 | #include <TColStd_MapOfInteger.hxx> | |
36 | #include <TColStd_MapIteratorOfMapOfInteger.hxx> | |
37 | #include <BRepMesh_FactoryError.hxx> | |
38 | #include <BRepMesh_DiscretRoot.hxx> | |
39 | #include <BRepMesh_DiscretFactory.hxx> | |
40 | #include <BRepMesh_PDiscretRoot.hxx> | |
41 | #include <gp_Vec.hxx> | |
42 | #include <StdPrs_WFShape.hxx> | |
43 | #include <BRepBndLib.hxx> | |
44 | #include <Precision.hxx> | |
45 | #ifdef G005 | |
46 | #include <Graphic3d_ArrayOfTriangles.hxx> | |
47 | #endif | |
48 | ||
49 | ||
50 | #define MAX2(X, Y) ( Abs(X) > Abs(Y)? Abs(X) : Abs(Y) ) | |
51 | #define MAX3(X, Y, Z) ( MAX2 ( MAX2(X,Y) , Z) ) | |
52 | ||
53 | ||
54 | static Standard_Real GetDeflection(const anyShape& aShape, | |
3c34883c | 55 | const Handle(Prs3d_Drawer)& aDrawer) |
7fd59977 | 56 | { |
3c34883c | 57 | Standard_Real aDeflection = aDrawer->MaximalChordialDeviation(); |
7fd59977 | 58 | if (aDrawer->TypeOfDeflection() == Aspect_TOD_RELATIVE) { |
59 | Bnd_Box B; | |
3c34883c | 60 | BRepBndLib::Add(aShape, B, Standard_False); |
7fd59977 | 61 | if ( ! B.IsVoid() ) |
62 | { | |
63 | Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax; | |
64 | B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); | |
65 | aDeflection = MAX3( aXmax-aXmin , aYmax-aYmin , aZmax-aZmin) | |
3c34883c | 66 | * aDrawer->DeviationCoefficient()*4; |
7fd59977 | 67 | } |
7fd59977 | 68 | } |
7fd59977 | 69 | return aDeflection; |
70 | } | |
71 | ||
72 | ||
73 | static Standard_Boolean ShadeFromShape(const anyShape& aShape, | |
3c34883c O |
74 | const Standard_Real /*defle*/, |
75 | const Standard_Boolean /*share*/, | |
76 | const Handle (Prs3d_Presentation)& aPresentation, | |
77 | const Handle (Prs3d_Drawer)& aDrawer) | |
7fd59977 | 78 | { |
3c34883c O |
79 | anyShadedShapeTool SST; |
80 | Handle(Poly_Triangulation) T; | |
81 | TopLoc_Location loc; | |
82 | gp_Pnt p; | |
83 | Standard_Integer i,j,k,decal ; | |
84 | Standard_Integer t[3], n[3]; | |
85 | Standard_Integer nbTriangles = 0, nbVertices = 0; | |
7fd59977 | 86 | |
3c34883c O |
87 | // precision for compare square distances |
88 | double dPreci = Precision::Confusion()*Precision::Confusion(); | |
7fd59977 | 89 | |
3c34883c | 90 | if ( !aDrawer->ShadingAspectGlobal() ) { |
7fd59977 | 91 | |
3c34883c O |
92 | Handle(Graphic3d_AspectFillArea3d) Asp = aDrawer->ShadingAspect()->Aspect(); |
93 | if(anyShadedShapeTool::IsClosed(aShape)) { | |
94 | Asp->SuppressBackFace(); | |
95 | } else { | |
96 | Asp->AllowBackFace(); | |
7fd59977 | 97 | } |
3c34883c O |
98 | Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(Asp); |
99 | } | |
7fd59977 | 100 | |
101 | #ifdef G005 | |
3c34883c O |
102 | if( Graphic3d_ArrayOfPrimitives::IsEnable() ) { |
103 | ||
104 | for (SST.Init(aShape); SST.MoreFace(); SST.NextFace()) { | |
105 | const anyTopFace& F = SST.CurrentFace(); | |
106 | T = SST.Triangulation(F, loc); | |
107 | if (!T.IsNull()) { | |
108 | nbTriangles += T->NbTriangles(); | |
109 | nbVertices += T->NbNodes(); | |
110 | } | |
111 | } | |
7fd59977 | 112 | |
3c34883c O |
113 | if (nbVertices > 2 && nbTriangles > 0) { |
114 | Handle(Graphic3d_ArrayOfTriangles) parray = | |
115 | new Graphic3d_ArrayOfTriangles(nbVertices,3*nbTriangles, | |
116 | Standard_True,Standard_False,Standard_False,Standard_True); | |
7fd59977 | 117 | for (SST.Init(aShape); SST.MoreFace(); SST.NextFace()) { |
118 | const anyTopFace& F = SST.CurrentFace(); | |
119 | T = SST.Triangulation(F, loc); | |
120 | if (!T.IsNull()) { | |
3c34883c O |
121 | const gp_Trsf& trsf = loc.Transformation(); |
122 | Poly_Connect pc(T); | |
123 | // Extracts vertices & normals from nodes | |
124 | const TColgp_Array1OfPnt& Nodes = T->Nodes(); | |
125 | TColgp_Array1OfDir NORMAL(Nodes.Lower(), Nodes.Upper()); | |
126 | SST.Normal(F, pc, NORMAL); | |
7fd59977 | 127 | |
3c34883c O |
128 | decal = parray->VertexNumber(); |
129 | for (i= Nodes.Lower(); i<= Nodes.Upper(); i++) { | |
130 | p = Nodes(i); | |
131 | if( !loc.IsIdentity() ) { | |
132 | p.Transform(trsf); | |
133 | NORMAL(i).Transform(trsf); | |
134 | } | |
135 | parray->AddVertex(p,NORMAL(i)); | |
136 | } | |
137 | ||
138 | // Fill parray with vertex and edge visibillity info | |
139 | const Poly_Array1OfTriangle& triangles = T->Triangles(); | |
140 | for (i = 1; i <= T->NbTriangles(); i++) { | |
141 | pc.Triangles(i,t[0],t[1],t[2]); | |
142 | if (SST.Orientation(F) == TopAbs_REVERSED) | |
143 | triangles(i).Get(n[0],n[2],n[1]); | |
144 | else | |
145 | triangles(i).Get(n[0],n[1],n[2]); | |
146 | gp_Pnt P1 = Nodes(n[0]); | |
147 | gp_Pnt P2 = Nodes(n[1]); | |
148 | gp_Pnt P3 = Nodes(n[2]); | |
149 | gp_Vec V1(P1,P2); | |
150 | if ( V1.SquareMagnitude() > dPreci ) { | |
151 | gp_Vec V2(P2,P3); | |
152 | if ( V2.SquareMagnitude() > dPreci ) { | |
153 | gp_Vec V3(P3,P1); | |
154 | if ( V3.SquareMagnitude() > dPreci ) { | |
155 | V1.Normalize(); | |
156 | V2.Normalize(); | |
157 | V1.Cross(V2); | |
158 | if ( V1.SquareMagnitude() > dPreci ) { | |
159 | parray->AddEdge(n[0]+decal,t[0] == 0); | |
160 | parray->AddEdge(n[1]+decal,t[1] == 0); | |
161 | parray->AddEdge(n[2]+decal,t[2] == 0); | |
162 | } | |
163 | } | |
164 | } | |
165 | } | |
166 | } | |
167 | } | |
168 | } | |
169 | Prs3d_Root::CurrentGroup(aPresentation)->BeginPrimitives(); | |
170 | Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(parray); | |
171 | Prs3d_Root::CurrentGroup(aPresentation)->EndPrimitives(); | |
172 | } | |
173 | return Standard_True; | |
174 | } | |
175 | #endif | |
7fd59977 | 176 | |
3c34883c O |
177 | // phase de comptage: |
178 | Standard_Integer nt, nnn, n1, n2, n3, nnv, EI; | |
179 | static Standard_Integer plus1mod3[3] = {1, 2, 0}; | |
180 | for (SST.Init(aShape); SST.MoreFace(); SST.NextFace()) { | |
181 | const anyTopFace& F = SST.CurrentFace(); | |
182 | T = SST.Triangulation(F, loc); | |
183 | if (!T.IsNull()) { | |
184 | nnn = T->NbTriangles(); | |
185 | const TColgp_Array1OfPnt& Nodes = T->Nodes(); | |
186 | const Poly_Array1OfTriangle& triangles = T->Triangles(); | |
187 | for (nt = 1; nt <= nnn; nt++) { | |
188 | if (SST.Orientation(F) == TopAbs_REVERSED) | |
189 | triangles(nt).Get(n1,n3,n2); | |
190 | else | |
191 | triangles(nt).Get(n1,n2,n3); | |
192 | const gp_Pnt& P1 = Nodes(n1); | |
193 | const gp_Pnt& P2 = Nodes(n2); | |
194 | const gp_Pnt& P3 = Nodes(n3); | |
195 | gp_Vec V1(P1,P2); | |
196 | if ( V1.SquareMagnitude() > dPreci ) { | |
197 | gp_Vec V2(P2,P3); | |
198 | if (V2.SquareMagnitude() > dPreci ) { | |
199 | gp_Vec V3(P3,P1); | |
200 | if (V3.SquareMagnitude() > dPreci ) { | |
201 | V1.Normalize(); | |
202 | V2.Normalize(); | |
203 | V1.Cross(V2); | |
204 | if (V1.SquareMagnitude() > dPreci ) { | |
205 | nbTriangles++; | |
206 | } | |
207 | } | |
7fd59977 | 208 | } |
3c34883c | 209 | } |
7fd59977 | 210 | } |
3c34883c | 211 | nbVertices += T->NbNodes(); |
7fd59977 | 212 | } |
3c34883c | 213 | } |
7fd59977 | 214 | |
3c34883c O |
215 | if (nbVertices > 2 && nbTriangles > 0) { |
216 | Graphic3d_Array1OfVertexN AVN(1, nbVertices); | |
217 | Aspect_Array1OfEdge AE(1, 3*nbTriangles); | |
218 | ||
219 | EI = 1; | |
220 | nnv = 1; | |
221 | ||
7fd59977 | 222 | for (SST.Init(aShape); SST.MoreFace(); SST.NextFace()) { |
223 | const anyTopFace& F = SST.CurrentFace(); | |
224 | T = SST.Triangulation(F, loc); | |
225 | if (!T.IsNull()) { | |
3c34883c O |
226 | Poly_Connect pc(T); |
227 | // 1- les noeuds. | |
228 | const TColgp_Array1OfPnt& Nodes = T->Nodes(); | |
229 | TColgp_Array1OfDir NORMAL(Nodes.Lower(), Nodes.Upper()); | |
230 | SST.Normal(F, pc, NORMAL); | |
231 | decal = nnv-1; | |
232 | ||
233 | for (j= Nodes.Lower(); j<= Nodes.Upper(); j++) { | |
234 | p = Nodes(j).Transformed(loc.Transformation()); | |
235 | AVN(nnv).SetCoord(p.X(), p.Y(), p.Z()); | |
236 | AVN(nnv).SetNormal(NORMAL(j).X(), NORMAL(j).Y(), NORMAL(j).Z()); | |
237 | nnv++; | |
7fd59977 | 238 | } |
3c34883c O |
239 | // 2- les edges. |
240 | nbTriangles = T->NbTriangles(); | |
241 | const Poly_Array1OfTriangle& triangles = T->Triangles(); | |
242 | ||
243 | for (i = 1; i <= nbTriangles; i++) { | |
244 | pc.Triangles(i,t[0],t[1],t[2]); | |
245 | if (SST.Orientation(F) == TopAbs_REVERSED) | |
246 | triangles(i).Get(n[0],n[2],n[1]); | |
247 | else | |
248 | triangles(i).Get(n[0],n[1],n[2]); | |
249 | const gp_Pnt& P1 = Nodes(n[0]); | |
250 | const gp_Pnt& P2 = Nodes(n[1]); | |
251 | const gp_Pnt& P3 = Nodes(n[2]); | |
252 | gp_Vec V1(P1,P2); | |
253 | if (V1.SquareMagnitude() > 1.e-10) { | |
254 | gp_Vec V2(P2,P3); | |
255 | if (V2.SquareMagnitude() > 1.e-10) { | |
256 | gp_Vec V3(P3,P1); | |
257 | if (V3.SquareMagnitude() > 1.e-10) { | |
258 | V1.Normalize(); | |
259 | V2.Normalize(); | |
260 | V1.Cross(V2); | |
261 | if (V1.SquareMagnitude() > 1.e-10) { | |
262 | for (j = 0; j < 3; j++) { | |
263 | k = plus1mod3[j]; | |
264 | if (t[j] == 0) | |
265 | AE(EI).SetValues(n[j]+decal, n[k]+decal, Aspect_TOE_VISIBLE); | |
266 | else | |
267 | AE(EI).SetValues(n[j]+decal, n[k]+decal, Aspect_TOE_INVISIBLE); | |
268 | EI++; | |
269 | } | |
270 | } | |
271 | } | |
272 | } | |
273 | } | |
274 | } | |
7fd59977 | 275 | } |
7fd59977 | 276 | } |
3c34883c O |
277 | Prs3d_Root::CurrentGroup(aPresentation)->TriangleSet(AVN, AE); |
278 | } | |
279 | return Standard_True; | |
7fd59977 | 280 | } |
281 | ||
282 | ||
283 | ||
284 | void Prs3d_ShadedShape::Add(const Handle (Prs3d_Presentation)& aPresentation, | |
3c34883c O |
285 | const anyShape& aShape, |
286 | const Handle (Prs3d_Drawer)& aDrawer) | |
7fd59977 | 287 | { |
288 | ||
289 | if (aShape.IsNull()) return; | |
290 | ||
291 | TopAbs_ShapeEnum E = aShape.ShapeType(); | |
292 | if (E == TopAbs_COMPOUND) { | |
293 | TopExp_Explorer ex; | |
294 | ||
295 | ex.Init(aShape, TopAbs_FACE); | |
296 | if (ex.More()) { | |
297 | TopoDS_Compound CO; | |
298 | BRep_Builder B; | |
299 | B.MakeCompound(CO); | |
300 | Standard_Boolean haselement = Standard_False; | |
301 | ||
302 | // il faut presenter les edges isoles. | |
303 | for (ex.Init(aShape, TopAbs_EDGE, TopAbs_FACE); ex.More(); ex.Next()) { | |
3c34883c O |
304 | haselement = Standard_True; |
305 | B.Add(CO, ex.Current()); | |
7fd59977 | 306 | } |
307 | // il faut presenter les vertex isoles. | |
308 | for (ex.Init(aShape, TopAbs_VERTEX, TopAbs_EDGE); ex.More(); ex.Next()) { | |
3c34883c O |
309 | haselement = Standard_True; |
310 | B.Add(CO, ex.Current()); | |
7fd59977 | 311 | } |
312 | if (haselement) StdPrs_WFShape::Add(aPresentation, CO, aDrawer); | |
313 | } | |
314 | else { | |
315 | StdPrs_WFShape::Add(aPresentation, aShape, aDrawer); | |
316 | } | |
317 | } | |
318 | Standard_Real aDeflection = GetDeflection(aShape, aDrawer); | |
319 | //using of plugin | |
3c34883c O |
320 | // Check if it is possible to avoid unnecessary recomputation |
321 | // of shape triangulation | |
322 | if( !BRepTools::Triangulation(aShape, aDeflection) ) | |
323 | { | |
324 | BRepTools::Clean(aShape); | |
7fd59977 | 325 | |
3c34883c O |
326 | BRepMesh_PDiscretRoot pAlgo; |
327 | pAlgo=BRepMesh_DiscretFactory::Get().Discret(aShape, | |
328 | aDeflection, | |
329 | aDrawer->HLRAngle()); | |
330 | if (pAlgo) | |
331 | pAlgo->Perform(); | |
332 | } | |
7fd59977 | 333 | ShadeFromShape(aShape, aDeflection, Standard_True, aPresentation, aDrawer); |
334 | } |