b311480e |
1 | // Created on: 2003-09-16 |
2 | // Created by: Alexander SOLOVYOV |
973c2be1 |
3 | // Copyright (c) 2003-2014 OPEN CASCADE SAS |
b311480e |
4 | // |
973c2be1 |
5 | // This file is part of Open CASCADE Technology software library. |
b311480e |
6 | // |
d5f74e42 |
7 | // This library is free software; you can redistribute it and/or modify it under |
8 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
9 | // by the Free Software Foundation, with special exception defined in the file |
10 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
11 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
12 | // |
973c2be1 |
13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. |
7fd59977 |
15 | |
7fd59977 |
16 | |
42cf5bc1 |
17 | #include <Aspect_InteriorStyle.hxx> |
a577aaab |
18 | #include <Graphic3d_ArrayOfPoints.hxx> |
42cf5bc1 |
19 | #include <Graphic3d_ArrayOfPolygons.hxx> |
7fd59977 |
20 | #include <Graphic3d_ArrayOfPolylines.hxx> |
42cf5bc1 |
21 | #include <Graphic3d_ArrayOfPrimitives.hxx> |
22 | #include <Graphic3d_ArrayOfSegments.hxx> |
23 | #include <Graphic3d_ArrayOfTriangles.hxx> |
24 | #include <Graphic3d_AspectFillArea3d.hxx> |
25 | #include <Graphic3d_AspectLine3d.hxx> |
26 | #include <Graphic3d_AspectMarker3d.hxx> |
7fd59977 |
27 | #include <Graphic3d_Group.hxx> |
42cf5bc1 |
28 | #include <MeshVS_Buffer.hxx> |
7fd59977 |
29 | #include <MeshVS_DataSource.hxx> |
30 | #include <MeshVS_Drawer.hxx> |
7fd59977 |
31 | #include <MeshVS_DrawerAttribute.hxx> |
32 | #include <MeshVS_MapOfTwoNodes.hxx> |
42cf5bc1 |
33 | #include <MeshVS_Mesh.hxx> |
34 | #include <MeshVS_MeshPrsBuilder.hxx> |
37ac4a67 |
35 | #include <MeshVS_SymmetricPairHasher.hxx> |
42cf5bc1 |
36 | #include <MeshVS_Tool.hxx> |
37ac4a67 |
37 | #include <NCollection_Map.hxx> |
38 | #include <NCollection_Vector.hxx> |
42cf5bc1 |
39 | #include <Prs3d_LineAspect.hxx> |
40 | #include <Prs3d_PointAspect.hxx> |
41 | #include <Prs3d_Presentation.hxx> |
42 | #include <Prs3d_Root.hxx> |
43 | #include <Prs3d_ShadingAspect.hxx> |
44 | #include <Quantity_NameOfColor.hxx> |
45 | #include <Select3D_SensitivePoint.hxx> |
46 | #include <Standard_Type.hxx> |
47 | #include <TColStd_Array1OfInteger.hxx> |
48 | #include <TColStd_Array1OfReal.hxx> |
49 | #include <TColStd_HPackedMapOfInteger.hxx> |
50 | #include <TColStd_ListIteratorOfListOfReal.hxx> |
51 | #include <TColStd_MapIntegerHasher.hxx> |
52 | #include <TColStd_MapIteratorOfPackedMapOfInteger.hxx> |
53 | #include <TColStd_MapOfInteger.hxx> |
54 | #include <TColStd_PackedMapOfInteger.hxx> |
55 | #include <TColStd_SequenceOfInteger.hxx> |
7fd59977 |
56 | |
57 | //================================================================ |
58 | // Function : Constructor MeshVS_MeshPrsBuilder |
59 | // Purpose : |
60 | //================================================================ |
61 | MeshVS_MeshPrsBuilder::MeshVS_MeshPrsBuilder ( const Handle(MeshVS_Mesh)& Parent, |
62 | const Standard_Integer& DisplayModeMask, |
63 | const Handle (MeshVS_DataSource)& DS, |
64 | const Standard_Integer Id, |
65 | const MeshVS_BuilderPriority& Priority ) |
66 | : MeshVS_PrsBuilder ( Parent, DisplayModeMask, DS, Id, Priority ) |
67 | { |
68 | } |
69 | |
70 | //================================================================ |
71 | // Function : Build |
72 | // Purpose : |
73 | //================================================================ |
74 | void MeshVS_MeshPrsBuilder::Build ( const Handle(Prs3d_Presentation)& Prs, |
75 | const TColStd_PackedMapOfInteger& IDs, |
76 | TColStd_PackedMapOfInteger& IDsToExclude, |
77 | const Standard_Boolean IsElement, |
78 | const Standard_Integer DisplayMode ) const |
79 | { |
80 | if ( DisplayMode <= 0 ) |
81 | return; |
82 | |
83 | Standard_Boolean HasHilightFlag = ( ( DisplayMode & MeshVS_DMF_HilightPrs ) != 0 ); |
84 | Standard_Integer Extent = IDs.Extent(); |
85 | |
86 | if ( HasHilightFlag && Extent == 1) |
87 | BuildHilightPrs ( Prs, IDs, IsElement ); |
88 | else if ( IsElement ) |
89 | BuildElements ( Prs, IDs, IDsToExclude, DisplayMode ); |
90 | else |
91 | BuildNodes ( Prs, IDs, IDsToExclude, DisplayMode ); |
92 | } |
93 | |
94 | //================================================================ |
95 | // Function : BuildNodes |
96 | // Purpose : |
97 | //================================================================ |
98 | void MeshVS_MeshPrsBuilder::BuildNodes ( const Handle(Prs3d_Presentation)& Prs, |
99 | const TColStd_PackedMapOfInteger& IDs, |
100 | TColStd_PackedMapOfInteger& IDsToExclude, |
101 | const Standard_Integer DisplayMode ) const |
102 | { |
103 | Handle( MeshVS_DataSource ) aSource = GetDataSource(); |
104 | Handle( MeshVS_Drawer ) aDrawer = GetDrawer(); |
105 | Handle (Graphic3d_AspectMarker3d) aNodeMark = |
106 | MeshVS_Tool::CreateAspectMarker3d( GetDrawer() ); |
107 | if ( aSource.IsNull() || aDrawer.IsNull() || aNodeMark.IsNull() ) |
108 | return; |
109 | |
110 | Standard_Boolean DisplayFreeNodes = Standard_True; |
111 | aDrawer->GetBoolean( MeshVS_DA_DisplayNodes, DisplayFreeNodes ); |
112 | Standard_Boolean HasSelectFlag = ( ( DisplayMode & MeshVS_DMF_SelectionPrs ) != 0 ); |
113 | Standard_Boolean HasHilightFlag = ( ( DisplayMode & MeshVS_DMF_HilightPrs ) != 0 ); |
114 | |
115 | Standard_Real aCoordsBuf[ 3 ]; |
116 | TColStd_Array1OfReal aCoords( *aCoordsBuf, 1, 3 ); |
117 | Standard_Integer NbNodes; |
118 | MeshVS_EntityType aType; |
119 | |
120 | if ( !DisplayFreeNodes ) |
121 | return; |
122 | |
123 | TColStd_PackedMapOfInteger anIDs; |
124 | anIDs.Assign( IDs ); |
125 | if ( !HasSelectFlag && !HasHilightFlag ) |
126 | { |
37ac4a67 |
127 | // subtract the hidden nodes and ids to exclude (to minimize allocated memory) |
7fd59977 |
128 | Handle(TColStd_HPackedMapOfInteger) aHiddenNodes = myParentMesh->GetHiddenNodes(); |
129 | if ( !aHiddenNodes.IsNull() ) |
130 | anIDs.Subtract( aHiddenNodes->Map() ); |
131 | } |
132 | anIDs.Subtract( IDsToExclude ); |
133 | |
134 | Standard_Integer upper = anIDs.Extent(); |
135 | if ( upper<=0 ) |
136 | return; |
137 | |
a577aaab |
138 | Handle(Graphic3d_ArrayOfPoints) aNodePoints = new Graphic3d_ArrayOfPoints (upper); |
7fd59977 |
139 | Standard_Integer k=0; |
140 | TColStd_MapIteratorOfPackedMapOfInteger it (anIDs); |
141 | for( ; it.More(); it.Next() ) |
142 | { |
143 | Standard_Integer aKey = it.Key(); |
144 | if ( aSource->GetGeom ( aKey, Standard_False, aCoords, NbNodes, aType ) ) |
145 | { |
146 | if ( IsExcludingOn() ) |
147 | IDsToExclude.Add (aKey); |
a577aaab |
148 | k++; |
149 | aNodePoints->AddVertex (aCoords(1), aCoords(2), aCoords(3)); |
7fd59977 |
150 | } |
151 | } |
152 | |
153 | if ( k>0 ) |
154 | { |
155 | Prs3d_Root::NewGroup ( Prs ); |
156 | Handle (Graphic3d_Group) aNodeGroup = Prs3d_Root::CurrentGroup ( Prs ); |
157 | aNodeGroup->SetPrimitivesAspect ( aNodeMark ); |
a577aaab |
158 | aNodeGroup->AddPrimitiveArray (aNodePoints); |
7fd59977 |
159 | } |
160 | } |
161 | |
162 | //================================================================ |
163 | // Function : BuildElements |
164 | // Purpose : |
165 | //================================================================ |
166 | void MeshVS_MeshPrsBuilder::BuildElements( const Handle(Prs3d_Presentation)& Prs, |
167 | const TColStd_PackedMapOfInteger& IDs, |
168 | TColStd_PackedMapOfInteger& IDsToExclude, |
169 | const Standard_Integer DisplayMode ) const |
170 | { |
37ac4a67 |
171 | Standard_Integer maxnodes; |
7fd59977 |
172 | |
37ac4a67 |
173 | Handle(MeshVS_DataSource) aSource = GetDataSource(); |
7fd59977 |
174 | if ( aSource.IsNull() ) |
175 | return; |
176 | |
177 | Handle( MeshVS_Drawer ) aDrawer = GetDrawer(); |
178 | if ( aDrawer.IsNull() || !aDrawer->GetInteger ( MeshVS_DA_MaxFaceNodes, maxnodes ) || |
179 | maxnodes <= 0 ) |
180 | return; |
181 | |
182 | //----------- extract useful display mode flags ---------- |
183 | Standard_Integer aDispMode = ( DisplayMode & GetFlags() ); |
184 | if ( ( aDispMode & MeshVS_DMF_DeformedMask) != 0 ) |
185 | { |
186 | aDispMode /= MeshVS_DMF_DeformedPrsWireFrame; |
187 | // This transformation turns deformed mesh flags to real display modes |
188 | } |
189 | aDispMode &= MeshVS_DMF_OCCMask; |
190 | //-------------------------------------------------------- |
191 | |
192 | Standard_Real aShrinkCoef; |
193 | aDrawer->GetDouble ( MeshVS_DA_ShrinkCoeff, aShrinkCoef ); |
194 | |
195 | Standard_Boolean IsWireFrame = ( aDispMode==MeshVS_DMF_WireFrame ), |
196 | IsShading = ( aDispMode==MeshVS_DMF_Shading ), |
197 | IsShrink = ( aDispMode==MeshVS_DMF_Shrink ), |
198 | HasHilightFlag = ( ( DisplayMode & MeshVS_DMF_HilightPrs ) != 0 ), |
199 | HasSelectFlag = ( ( DisplayMode & MeshVS_DMF_SelectionPrs ) != 0 ), |
200 | IsMeshReflect, IsMeshAllowOverlap, IsReflect, IsMeshSmoothShading = Standard_False; |
201 | |
202 | aDrawer->GetBoolean ( MeshVS_DA_Reflection, IsMeshReflect ); |
203 | aDrawer->GetBoolean ( MeshVS_DA_IsAllowOverlapped, IsMeshAllowOverlap ); |
204 | IsReflect = ( IsMeshReflect && !HasHilightFlag ); |
205 | aDrawer->GetBoolean ( MeshVS_DA_SmoothShading, IsMeshSmoothShading ); |
206 | |
37ac4a67 |
207 | // display mode for highlighted prs of groups |
7fd59977 |
208 | IsShrink = ( IsShrink && !HasHilightFlag ); |
209 | IsShading = ( IsShading || HasHilightFlag ); |
210 | |
211 | //---------- Creating AspectFillArea3d and AspectLine3d ------------- |
212 | Graphic3d_MaterialAspect AMat; |
213 | aDrawer->GetMaterial ( MeshVS_DA_FrontMaterial, AMat ); |
214 | if ( !IsReflect ) |
215 | { |
216 | AMat.SetReflectionModeOff(Graphic3d_TOR_AMBIENT); |
217 | AMat.SetReflectionModeOff(Graphic3d_TOR_DIFFUSE); |
218 | AMat.SetReflectionModeOff(Graphic3d_TOR_SPECULAR); |
219 | AMat.SetReflectionModeOff(Graphic3d_TOR_EMISSION); |
220 | } |
221 | Handle( Graphic3d_AspectFillArea3d ) aFill = MeshVS_Tool::CreateAspectFillArea3d( GetDrawer(), AMat ); |
222 | Handle( Graphic3d_AspectLine3d ) aBeam = MeshVS_Tool::CreateAspectLine3d ( GetDrawer() ); |
223 | //------------------------------------------------------------------- |
224 | |
225 | Standard_Boolean IsOverlapControl = |
226 | !IsMeshAllowOverlap && ( IsWireFrame || IsShading ) && !HasSelectFlag; |
227 | |
37ac4a67 |
228 | // subtract the hidden elements and ids to exclude (to minimize allocated memory) |
7fd59977 |
229 | TColStd_PackedMapOfInteger anIDs; |
230 | anIDs.Assign( IDs ); |
231 | Handle(TColStd_HPackedMapOfInteger) aHiddenElems = myParentMesh->GetHiddenElems(); |
232 | if ( !aHiddenElems.IsNull() ) |
233 | anIDs.Subtract( aHiddenElems->Map() ); |
234 | anIDs.Subtract( IDsToExclude ); |
235 | |
236 | Handle( MeshVS_HArray1OfSequenceOfInteger ) aTopo; |
237 | TColStd_MapIteratorOfPackedMapOfInteger it (anIDs); |
37ac4a67 |
238 | |
239 | Standard_Boolean showEdges = Standard_True; |
240 | aDrawer->GetBoolean( MeshVS_DA_ShowEdges, showEdges ); |
241 | |
242 | showEdges = IsWireFrame || showEdges; |
243 | |
244 | Standard_Integer* aNodesBuf = (Standard_Integer*) alloca (maxnodes * sizeof (Standard_Integer)); |
245 | Standard_Real* aCoordsBuf = (Standard_Real*) alloca (3 * maxnodes * sizeof (Standard_Real)); |
246 | |
247 | TColStd_Array1OfInteger aNodes (*aNodesBuf, 1, maxnodes); |
248 | TColStd_Array1OfReal aCoords (*aCoordsBuf, 1, 3 * maxnodes); |
249 | |
250 | Standard_Integer aNbFacePrimitives = 0; |
251 | Standard_Integer aNbVolmPrimitives = 0; |
252 | Standard_Integer aNbEdgePrimitives = 0; |
253 | Standard_Integer aNbLinkPrimitives = 0; |
254 | |
255 | MeshVS_EntityType aType; |
256 | |
257 | for (it.Reset(); it.More(); it.Next()) |
7fd59977 |
258 | { |
37ac4a67 |
259 | Standard_Integer aNbNodes = 0; |
260 | |
261 | if (!aSource->GetGeom (it.Key(), Standard_True, aCoords, aNbNodes, aType)) |
262 | continue; |
263 | |
264 | if (aType == MeshVS_ET_Volume) |
7fd59977 |
265 | { |
37ac4a67 |
266 | if (aSource->Get3DGeom (it.Key(), aNbNodes, aTopo)) |
267 | { |
268 | for (Standard_Integer aFaceIdx = aTopo->Lower(); aFaceIdx <= aTopo->Upper(); ++aFaceIdx) |
269 | { |
270 | const TColStd_SequenceOfInteger& aFaceNodes = aTopo->Value (aFaceIdx); |
271 | |
272 | if (showEdges) // add edge segments |
273 | { |
274 | aNbEdgePrimitives += aFaceNodes.Length(); |
275 | } |
276 | |
277 | if (IsShading || IsShrink) // add volumetric cell triangles |
278 | { |
279 | if (!HasSelectFlag) |
280 | aNbVolmPrimitives += aFaceNodes.Length() - 2; |
281 | } |
282 | } |
283 | } |
284 | } |
285 | else if (aType == MeshVS_ET_Link) |
286 | { |
287 | if (showEdges) |
288 | { |
289 | aNbLinkPrimitives += 1; // add link segment |
290 | } |
291 | } |
292 | else if (aType == MeshVS_ET_Face) |
293 | { |
294 | if (showEdges) |
295 | { |
296 | aNbEdgePrimitives += aNbNodes; // add edge segments |
297 | } |
298 | |
299 | if (!IsOverlapControl || IsShading) |
300 | { |
301 | if ((IsShading || IsShrink) && !HasSelectFlag) |
302 | { |
303 | aNbFacePrimitives += aNbNodes - 2; // add face triangles |
304 | } |
305 | } |
7fd59977 |
306 | } |
307 | } |
308 | |
37ac4a67 |
309 | // Here we do not use indices arrays because they are not effective for some mesh |
310 | // drawing modes: shrinking mode (displaces the vertices inside the polygon), 3D |
311 | // cell rendering (normal interpolation is not always applicable - flat shading), |
312 | // elemental coloring (color interpolation is impossible) |
313 | Handle (Graphic3d_ArrayOfTriangles) aVolmTriangles = |
314 | new Graphic3d_ArrayOfTriangles (aNbVolmPrimitives * 3, 0, IsReflect); |
315 | Handle (Graphic3d_ArrayOfTriangles) aFaceTriangles = |
316 | new Graphic3d_ArrayOfTriangles (aNbFacePrimitives * 3, 0, IsReflect); |
7fd59977 |
317 | |
37ac4a67 |
318 | Handle (Graphic3d_ArrayOfSegments) aLinkSegments; |
319 | Handle (Graphic3d_ArrayOfSegments) aEdgeSegments; |
320 | |
321 | if (showEdges) |
7fd59977 |
322 | { |
37ac4a67 |
323 | aLinkSegments = new Graphic3d_ArrayOfSegments (aNbLinkPrimitives * 2); |
324 | aEdgeSegments = new Graphic3d_ArrayOfSegments (aNbEdgePrimitives * 2); |
7fd59977 |
325 | } |
326 | |
7fd59977 |
327 | TColStd_PackedMapOfInteger aCustomElements; |
328 | |
329 | Quantity_Color anOldEdgeColor; |
37ac4a67 |
330 | Quantity_Color anEdgeColor; |
331 | Quantity_Color anIntColor; |
7fd59977 |
332 | Aspect_InteriorStyle anIntType; |
7fd59977 |
333 | Aspect_TypeOfLine aLine; |
334 | Standard_Real aWidth; |
335 | |
37ac4a67 |
336 | aFill->Values (anIntType, anIntColor, anEdgeColor, aLine, aWidth); |
7fd59977 |
337 | |
338 | MeshVS_MapOfTwoNodes aLinkNodes; |
37ac4a67 |
339 | |
340 | // Forbid drawings of edges which overlap with some links |
341 | if (showEdges && IsOverlapControl) |
342 | { |
343 | for (it.Reset(); it.More(); it.Next()) |
7fd59977 |
344 | { |
37ac4a67 |
345 | if (aSource->GetGeomType (it.Key(), Standard_True, aType) && aType == MeshVS_ET_Link) |
7fd59977 |
346 | { |
37ac4a67 |
347 | Standard_Integer aNbNodes; |
348 | |
349 | if (aSource->GetNodesByElement (it.Key(), aNodes, aNbNodes) && aNbNodes == 2) |
7fd59977 |
350 | { |
37ac4a67 |
351 | aLinkNodes.Add (MeshVS_TwoNodes (aNodes(1), aNodes(2))); |
7fd59977 |
352 | } |
353 | } |
354 | } |
37ac4a67 |
355 | } |
356 | |
357 | NCollection_Map<MeshVS_NodePair, MeshVS_SymmetricPairHasher> aSegmentMap; |
7fd59977 |
358 | |
37ac4a67 |
359 | for (it.Reset(); it.More(); it.Next()) |
7fd59977 |
360 | { |
37ac4a67 |
361 | const Standard_Integer aKey = it.Key(); |
362 | |
363 | Standard_Integer NbNodes; |
364 | if (!aSource->GetGeom (aKey, Standard_True, aCoords, NbNodes, aType)) |
365 | continue; |
7fd59977 |
366 | |
37ac4a67 |
367 | if (!aSource->GetNodesByElement (aKey, aNodes, NbNodes)) |
7fd59977 |
368 | continue; |
369 | |
37ac4a67 |
370 | switch (aType) |
7fd59977 |
371 | { |
37ac4a67 |
372 | case MeshVS_ET_Volume: |
373 | { |
374 | if (IsExcludingOn()) |
7fd59977 |
375 | IDsToExclude.Add (aKey); |
37ac4a67 |
376 | |
377 | if (aSource->Get3DGeom (aKey, NbNodes, aTopo)) |
7fd59977 |
378 | { |
37ac4a67 |
379 | // Add wire-frame presentation (draw edges for shading mode as well) |
380 | if (showEdges) |
381 | { |
382 | AddVolumePrs (aTopo, aCoords, NbNodes, |
383 | aEdgeSegments, IsReflect, IsShrink, HasSelectFlag, aShrinkCoef); |
384 | } |
385 | |
386 | // Add shading presentation |
387 | if ((IsShading || IsShrink) && !HasSelectFlag) |
388 | { |
389 | AddVolumePrs (aTopo, aCoords, NbNodes, |
390 | aVolmTriangles, IsReflect, IsShrink, HasSelectFlag, aShrinkCoef); |
391 | } |
7fd59977 |
392 | } |
37ac4a67 |
393 | } |
394 | break; |
7fd59977 |
395 | |
37ac4a67 |
396 | case MeshVS_ET_Link: |
397 | { |
398 | if (IsExcludingOn()) |
7fd59977 |
399 | IDsToExclude.Add (aKey); |
7fd59977 |
400 | |
37ac4a67 |
401 | if (showEdges) |
7fd59977 |
402 | { |
37ac4a67 |
403 | AddLinkPrs (aCoords, aLinkSegments, IsShrink || HasSelectFlag, aShrinkCoef); |
404 | } |
405 | } |
406 | break; |
7fd59977 |
407 | |
37ac4a67 |
408 | case MeshVS_ET_Face: |
409 | { |
410 | if (IsExcludingOn()) |
411 | IDsToExclude.Add (aKey); |
412 | |
413 | if (showEdges && IsOverlapControl) |
414 | { |
7fd59977 |
415 | Standard_Integer Last = 0; |
37ac4a67 |
416 | |
417 | MeshVS_TwoNodes aTwoNodes (aNodes (1)); |
418 | |
419 | for (Standard_Integer i = 1; i <= NbNodes; ++i) |
7fd59977 |
420 | { |
37ac4a67 |
421 | if (i > 1) |
7fd59977 |
422 | aTwoNodes.First = aTwoNodes.Second; |
423 | |
37ac4a67 |
424 | aTwoNodes.Second = (i < NbNodes) ? aNodes (i+1) : aNodes (1); |
425 | |
426 | if (aLinkNodes.Contains (aTwoNodes)) |
427 | { |
428 | for (Standard_Integer aNodeIdx = Last + 1; aNodeIdx < i; ++aNodeIdx) |
7fd59977 |
429 | { |
37ac4a67 |
430 | const Standard_Integer aNextIdx = aNodeIdx + 1; |
431 | |
432 | aEdgeSegments->AddVertex ( |
433 | aCoords (3 * aNodeIdx - 2), aCoords (3 * aNodeIdx - 1), aCoords (3 * aNodeIdx)); |
434 | aEdgeSegments->AddVertex ( |
435 | aCoords (3 * aNextIdx - 2), aCoords (3 * aNextIdx - 1), aCoords (3 * aNextIdx)); |
7fd59977 |
436 | } |
37ac4a67 |
437 | |
438 | Last = i; |
439 | } |
7fd59977 |
440 | } |
37ac4a67 |
441 | |
442 | if (NbNodes - Last > 0) |
7fd59977 |
443 | { |
37ac4a67 |
444 | for (Standard_Integer aNodeIdx = Last; aNodeIdx < NbNodes; ++aNodeIdx) |
445 | { |
446 | const Standard_Integer aNextIdx = (aNodeIdx + 1) % NbNodes; |
447 | |
448 | const MeshVS_NodePair aSegment (aNodes (aNodeIdx + 1), |
449 | aNodes (aNextIdx + 1)); |
450 | |
451 | if (!aSegmentMap.Contains (aSegment)) |
452 | { |
453 | aEdgeSegments->AddVertex (aCoords (3 * aNodeIdx + 1), |
454 | aCoords (3 * aNodeIdx + 2), |
455 | aCoords (3 * aNodeIdx + 3)); |
7fd59977 |
456 | |
37ac4a67 |
457 | aEdgeSegments->AddVertex (aCoords (3 * aNextIdx + 1), |
458 | aCoords (3 * aNextIdx + 2), |
459 | aCoords (3 * aNextIdx + 3)); |
460 | |
461 | aSegmentMap.Add (aSegment); |
462 | } |
463 | } |
7fd59977 |
464 | } |
465 | } |
466 | |
37ac4a67 |
467 | if (!IsOverlapControl || IsShading) |
7fd59977 |
468 | { |
37ac4a67 |
469 | if (!IsOverlapControl && showEdges) |
470 | { |
471 | AddFaceWirePrs (aCoords, NbNodes, |
472 | aEdgeSegments, IsShrink || HasSelectFlag, aShrinkCoef); |
473 | } |
474 | |
475 | if ((IsShading || IsShrink) && !HasSelectFlag) |
476 | { |
477 | AddFaceSolidPrs (aKey, aCoords, NbNodes, maxnodes, aFaceTriangles, IsReflect, |
478 | IsShrink || HasSelectFlag, aShrinkCoef, IsMeshSmoothShading); |
479 | } |
7fd59977 |
480 | } |
37ac4a67 |
481 | } |
482 | break; |
7fd59977 |
483 | |
484 | default: |
37ac4a67 |
485 | { |
486 | aCustomElements.Add (aKey); |
487 | } |
7fd59977 |
488 | } |
489 | } |
490 | |
37ac4a67 |
491 | if (IsShrink) |
7fd59977 |
492 | { |
493 | anOldEdgeColor = anEdgeColor; |
37ac4a67 |
494 | aFill->SetEdgeColor (Quantity_NOC_BLACK); |
7fd59977 |
495 | } |
496 | |
37ac4a67 |
497 | //std::cout << "Actual extents: " << std::endl |
498 | // << "Face tris: " << aFaceTriangles->ItemNumber() << " from " << aNbFacePrimitives << std::endl |
499 | // << "Volm tris: " << aVolmTriangles->ItemNumber() << " from " << aNbVolmPrimitives << std::endl |
500 | // << "Face segs: " << aEdgeSegments->ItemNumber() << " from " << aNbEdgePrimitives << std::endl |
501 | // << "Link segs: " << aLinkSegments->ItemNumber() << " from " << aNbLinkPrimitives << std::endl; |
502 | |
503 | DrawArrays ( Prs, aFaceTriangles, aEdgeSegments, aLinkSegments, aVolmTriangles, |
7fd59977 |
504 | !showEdges, HasSelectFlag, aFill, aBeam ); |
505 | |
506 | if ( !aCustomElements.IsEmpty() ) |
507 | CustomBuild ( Prs, aCustomElements, IDsToExclude, DisplayMode ); |
508 | |
509 | if( IsShrink ) |
510 | aFill->SetEdgeColor( anOldEdgeColor ); |
511 | } |
512 | |
513 | //================================================================ |
514 | // Function : BuildHilightPrs |
515 | // Purpose : |
516 | //================================================================ |
517 | void MeshVS_MeshPrsBuilder::BuildHilightPrs ( const Handle(Prs3d_Presentation)& Prs, |
518 | const TColStd_PackedMapOfInteger& IDs, |
519 | const Standard_Boolean IsElement ) const |
520 | { |
521 | Standard_Integer maxnodes; |
522 | |
523 | Handle (MeshVS_DataSource) aSource = GetDataSource(); |
524 | if ( aSource.IsNull() || IDs.IsEmpty() ) |
525 | return; |
526 | |
527 | Handle( MeshVS_Drawer ) aDrawer = GetDrawer(); |
528 | if ( aDrawer.IsNull() || !aDrawer->GetInteger ( MeshVS_DA_MaxFaceNodes, maxnodes ) || |
529 | maxnodes <= 0 ) |
530 | return; |
531 | |
532 | MeshVS_Buffer aCoordsBuf (3*maxnodes*sizeof(Standard_Real)); |
533 | TColStd_Array1OfReal aCoords (aCoordsBuf, 1, 3*maxnodes); |
534 | |
535 | Graphic3d_MaterialAspect AMat; |
536 | aDrawer->GetMaterial ( MeshVS_DA_FrontMaterial, AMat ); |
537 | AMat.SetReflectionModeOff(Graphic3d_TOR_AMBIENT); |
538 | AMat.SetReflectionModeOff(Graphic3d_TOR_DIFFUSE); |
539 | AMat.SetReflectionModeOff(Graphic3d_TOR_SPECULAR); |
540 | AMat.SetReflectionModeOff(Graphic3d_TOR_EMISSION); |
541 | |
542 | Handle( Graphic3d_AspectFillArea3d ) aFill = MeshVS_Tool::CreateAspectFillArea3d( GetDrawer(), AMat ); |
543 | Handle( Graphic3d_AspectLine3d ) aBeam = MeshVS_Tool::CreateAspectLine3d( GetDrawer() ); |
544 | Handle( Graphic3d_AspectMarker3d ) aNodeMark = MeshVS_Tool::CreateAspectMarker3d( GetDrawer() ); |
545 | |
546 | // Hilight one element or node |
547 | TColStd_MapIteratorOfPackedMapOfInteger it (IDs); |
548 | Standard_Integer ID = it.Key(), NbNodes; |
549 | MeshVS_EntityType aType; |
550 | |
551 | if ( !aSource->GetGeom ( ID, IsElement, aCoords, NbNodes, aType ) ) |
552 | return; |
553 | |
554 | Prs3d_Root::NewGroup ( Prs ); |
555 | Handle (Graphic3d_Group) aHilightGroup = Prs3d_Root::CurrentGroup ( Prs ); |
556 | |
557 | switch ( aType ) |
558 | { |
559 | case MeshVS_ET_Node : |
560 | { |
a577aaab |
561 | aHilightGroup->SetPrimitivesAspect (aNodeMark); |
562 | Handle(Graphic3d_ArrayOfPoints) anArrayOfPoints = new Graphic3d_ArrayOfPoints (1); |
563 | anArrayOfPoints->AddVertex (aCoords(1), aCoords(2), aCoords(3)); |
564 | aHilightGroup->AddPrimitiveArray (anArrayOfPoints); |
7fd59977 |
565 | } |
566 | break; |
567 | |
568 | case MeshVS_ET_Link: |
569 | { |
570 | aHilightGroup->SetPrimitivesAspect ( aBeam ); |
b8ddfc2f |
571 | Handle(Graphic3d_ArrayOfSegments) aPrims = new Graphic3d_ArrayOfSegments(2); |
572 | aPrims->AddVertex(aCoords(1),aCoords(2),aCoords(3)); |
573 | aPrims->AddVertex(aCoords(4),aCoords(5),aCoords(6)); |
574 | aHilightGroup->AddPrimitiveArray(aPrims); |
7fd59977 |
575 | } |
576 | break; |
577 | |
578 | case MeshVS_ET_Face: |
579 | if ( NbNodes > 0 ) |
580 | { |
7fd59977 |
581 | aHilightGroup->SetPrimitivesAspect ( aFill ); |
b8ddfc2f |
582 | Handle(Graphic3d_ArrayOfPolygons) aPrims = new Graphic3d_ArrayOfPolygons(NbNodes); |
7fd59977 |
583 | for ( Standard_Integer k=1; k<=NbNodes; k++) |
b8ddfc2f |
584 | aPrims->AddVertex(aCoords(3*k-2),aCoords(3*k-1),aCoords(3*k)); |
585 | aHilightGroup->AddPrimitiveArray(aPrims); |
7fd59977 |
586 | } |
587 | break; |
588 | |
589 | case MeshVS_ET_Volume: |
590 | if( NbNodes > 0 ) |
591 | { |
592 | Handle( MeshVS_HArray1OfSequenceOfInteger ) aTopo; |
593 | |
594 | aHilightGroup->SetPrimitivesAspect ( aFill ); |
595 | |
596 | if( aSource->Get3DGeom( ID, NbNodes, aTopo ) ) |
597 | { |
b8ddfc2f |
598 | const Standard_Integer up = aTopo->Upper(); |
599 | const Standard_Integer lo = aTopo->Lower(); |
600 | Standard_Integer nbnodes = 0, i, j; |
601 | for( i=lo; i<=up; i++ ) |
602 | nbnodes += aTopo->Value( i ).Length(); |
603 | |
604 | Handle(Graphic3d_ArrayOfPolygons) aPrims = new Graphic3d_ArrayOfPolygons(nbnodes,aTopo->Length()); |
605 | for( i=lo; i<=up; i++ ) |
7fd59977 |
606 | { |
607 | const TColStd_SequenceOfInteger& aSeq = aTopo->Value( i ); |
b8ddfc2f |
608 | const Standard_Integer m = aSeq.Length(); |
609 | aPrims->AddBound(m); |
7fd59977 |
610 | for( j=1; j<=m; j++ ) |
611 | { |
b8ddfc2f |
612 | const Standard_Integer ind = 3*aSeq.Value( j ); |
613 | aPrims->AddVertex(aCoords(ind+1),aCoords(ind+2),aCoords(ind+3)); |
7fd59977 |
614 | } |
7fd59977 |
615 | } |
b8ddfc2f |
616 | aHilightGroup->AddPrimitiveArray(aPrims); |
7fd59977 |
617 | } |
618 | } |
619 | break; |
620 | |
621 | default: |
622 | { |
623 | TColStd_PackedMapOfInteger tmp; |
624 | CustomBuild ( Prs, IDs, tmp, MeshVS_DMF_HilightPrs ); |
625 | } |
626 | break; |
627 | } |
628 | } |
629 | |
630 | //================================================================ |
631 | // Function : AddLinkPrs |
632 | // Purpose : |
633 | //================================================================ |
37ac4a67 |
634 | void MeshVS_MeshPrsBuilder::AddLinkPrs (const TColStd_Array1OfReal& theCoords, |
635 | const Handle(Graphic3d_ArrayOfSegments)& theSegments, |
636 | const Standard_Boolean theIsShrinked, |
637 | const Standard_Real theShrinkCoef) const |
7fd59977 |
638 | { |
37ac4a67 |
639 | Standard_Real aX1 = theCoords (1); |
640 | Standard_Real aY1 = theCoords (2); |
641 | Standard_Real aZ1 = theCoords (3); |
642 | Standard_Real aX2 = theCoords (4); |
643 | Standard_Real aY2 = theCoords (5); |
644 | Standard_Real aZ2 = theCoords (6); |
645 | |
646 | if (theIsShrinked) |
7fd59977 |
647 | { |
37ac4a67 |
648 | const Standard_Real xG = (aX1 + aX2) * 0.5; |
649 | const Standard_Real yG = (aY1 + aY2) * 0.5; |
650 | const Standard_Real zG = (aZ1 + aZ2) * 0.5; |
651 | |
652 | aX1 = (aX1 - xG) * theShrinkCoef + xG; |
653 | aY1 = (aY1 - yG) * theShrinkCoef + yG; |
654 | aZ1 = (aZ1 - zG) * theShrinkCoef + zG; |
655 | |
656 | aX2 = 2.0 * xG - aX1; |
657 | aY2 = 2.0 * yG - aY1; |
658 | aZ2 = 2.0 * zG - aZ1; |
7fd59977 |
659 | } |
37ac4a67 |
660 | |
661 | theSegments->AddVertex (aX1, aY1, aZ1); |
662 | theSegments->AddVertex (aX2, aY2, aZ2); |
7fd59977 |
663 | } |
664 | |
665 | //================================================================ |
666 | // Function : AddFaceWirePrs |
667 | // Purpose : |
668 | //================================================================ |
37ac4a67 |
669 | void MeshVS_MeshPrsBuilder::AddFaceWirePrs (const TColStd_Array1OfReal& theCoords, |
670 | const Standard_Integer theNbNodes, |
671 | const Handle(Graphic3d_ArrayOfSegments)& theSegments, |
672 | const Standard_Boolean theIsShrinked, |
673 | const Standard_Real theShrinkingCoef) const |
7fd59977 |
674 | { |
37ac4a67 |
675 | Standard_Real aCenterX = 0.0; |
676 | Standard_Real aCenterY = 0.0; |
677 | Standard_Real aCenterZ = 0.0; |
7fd59977 |
678 | |
37ac4a67 |
679 | if (theIsShrinked) |
7fd59977 |
680 | { |
37ac4a67 |
681 | CalculateCenter (theCoords, theNbNodes, aCenterX, aCenterY, aCenterZ); |
682 | } |
683 | |
684 | NCollection_Vector<gp_XYZ> aNodes (theNbNodes); |
685 | |
686 | for (Standard_Integer aNodeIdx = 0; aNodeIdx < theNbNodes; ++aNodeIdx) |
687 | { |
688 | gp_XYZ aPnt (theCoords (3 * aNodeIdx + 1), |
689 | theCoords (3 * aNodeIdx + 2), |
690 | theCoords (3 * aNodeIdx + 3)); |
691 | |
692 | if (theIsShrinked) |
7fd59977 |
693 | { |
37ac4a67 |
694 | aPnt.SetX ((aPnt.X() - aCenterX) * theShrinkingCoef + aCenterX); |
695 | aPnt.SetY ((aPnt.Y() - aCenterY) * theShrinkingCoef + aCenterY); |
696 | aPnt.SetZ ((aPnt.Z() - aCenterZ) * theShrinkingCoef + aCenterZ); |
7fd59977 |
697 | } |
37ac4a67 |
698 | |
699 | aNodes.Append (aPnt); |
700 | } |
701 | |
702 | for (Standard_Integer aNodeIdx = 0; aNodeIdx < theNbNodes; ++aNodeIdx) |
703 | { |
704 | theSegments->AddVertex (aNodes.Value (aNodeIdx).X(), |
705 | aNodes.Value (aNodeIdx).Y(), |
706 | aNodes.Value (aNodeIdx).Z()); |
707 | |
708 | const Standard_Integer aNextIdx = (aNodeIdx + 1) % theNbNodes; |
709 | |
710 | theSegments->AddVertex (aNodes.Value (aNextIdx).X(), |
711 | aNodes.Value (aNextIdx).Y(), |
712 | aNodes.Value (aNextIdx).Z()); |
7fd59977 |
713 | } |
7fd59977 |
714 | } |
715 | |
716 | //================================================================ |
717 | // Function : AddFaceSolidPrs |
718 | // Purpose : |
719 | //================================================================ |
37ac4a67 |
720 | void MeshVS_MeshPrsBuilder::AddFaceSolidPrs (const Standard_Integer theID, |
721 | const TColStd_Array1OfReal& theCoords, |
722 | const Standard_Integer theNbNodes, |
723 | const Standard_Integer theMaxNodes, |
724 | const Handle(Graphic3d_ArrayOfTriangles)& theTriangles, |
725 | const Standard_Boolean theIsShaded, |
726 | const Standard_Boolean theIsShrinked, |
727 | const Standard_Real theShrinkingCoef, |
728 | const Standard_Boolean theIsSmoothShading) const |
7fd59977 |
729 | { |
37ac4a67 |
730 | Handle(MeshVS_DataSource) aDataSource = myParentMesh->GetDataSource(); |
731 | |
732 | if (aDataSource.IsNull()) |
7fd59977 |
733 | return; |
734 | |
37ac4a67 |
735 | Standard_Real aCenterX = 0.0; |
736 | Standard_Real aCenterY = 0.0; |
737 | Standard_Real aCenterZ = 0.0; |
738 | Standard_Real aNormalX = 0.0; |
739 | Standard_Real aNormalY = 0.0; |
740 | Standard_Real aNormalZ = 0.0; |
7fd59977 |
741 | |
37ac4a67 |
742 | if (theIsShrinked) |
743 | { |
744 | CalculateCenter (theCoords, theNbNodes, aCenterX, aCenterY, aCenterZ); |
745 | } |
7fd59977 |
746 | |
37ac4a67 |
747 | NCollection_Vector<gp_XYZ> aVertexNormals (theMaxNodes); |
748 | |
749 | if (theIsShaded) |
7fd59977 |
750 | { |
37ac4a67 |
751 | if (theIsSmoothShading) |
752 | { |
753 | for (Standard_Integer aNodeIdx = 1; aNodeIdx <= theNbNodes; ++aNodeIdx) |
754 | { |
755 | if (!aDataSource->GetNodeNormal (aNodeIdx, theID, aNormalX, aNormalY, aNormalZ)) |
756 | break; |
757 | |
758 | aVertexNormals.Append (gp_XYZ (aNormalX, aNormalY, aNormalZ)); |
759 | } |
760 | } |
761 | |
762 | if (!theIsSmoothShading || aVertexNormals.Size() != theNbNodes) |
763 | { |
764 | aDataSource->GetNormal (theID, theMaxNodes, aNormalX, aNormalY, aNormalZ); |
765 | } |
7fd59977 |
766 | } |
767 | |
37ac4a67 |
768 | NCollection_Vector<gp_XYZ> aNodes (theMaxNodes); |
769 | |
770 | for (Standard_Integer aNodeIdx = 0; aNodeIdx < theNbNodes; ++aNodeIdx) |
7fd59977 |
771 | { |
37ac4a67 |
772 | gp_XYZ aPnt (theCoords (3 * aNodeIdx + 1), |
773 | theCoords (3 * aNodeIdx + 2), |
774 | theCoords (3 * aNodeIdx + 3)); |
775 | |
776 | if (theIsShrinked) |
7fd59977 |
777 | { |
37ac4a67 |
778 | aPnt.SetX ((aPnt.X() - aCenterX) * theShrinkingCoef + aCenterX); |
779 | aPnt.SetY ((aPnt.Y() - aCenterY) * theShrinkingCoef + aCenterY); |
780 | aPnt.SetZ ((aPnt.Z() - aCenterZ) * theShrinkingCoef + aCenterZ); |
7fd59977 |
781 | } |
782 | |
37ac4a67 |
783 | aNodes.Append (aPnt); |
784 | } |
785 | |
786 | // Triangulate polygon |
787 | for (Standard_Integer aNodeIdx = 0; aNodeIdx < theNbNodes - 2; ++aNodeIdx) |
788 | { |
789 | for (Standard_Integer aSubIdx = 0; aSubIdx < 3; ++aSubIdx) |
7fd59977 |
790 | { |
37ac4a67 |
791 | if (theIsShaded) |
792 | { |
793 | if (theIsSmoothShading && aVertexNormals.Size() == theNbNodes) |
794 | { |
795 | aNormalX = aVertexNormals.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).X(); |
796 | aNormalY = aVertexNormals.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).Y(); |
797 | aNormalZ = aVertexNormals.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).Z(); |
798 | } |
799 | |
800 | theTriangles->AddVertex (aNodes.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).X(), |
801 | aNodes.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).Y(), |
802 | aNodes.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).Z(), |
803 | aNormalX, |
804 | aNormalY, |
805 | aNormalZ); |
806 | } |
807 | else |
808 | { |
809 | theTriangles->AddVertex (aNodes.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).X(), |
810 | aNodes.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).Y(), |
811 | aNodes.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).Z()); |
812 | } |
7fd59977 |
813 | } |
7fd59977 |
814 | } |
815 | } |
816 | |
817 | //================================================================ |
818 | // Function : AddVolumePrs |
819 | // Purpose : |
820 | //================================================================ |
37ac4a67 |
821 | void MeshVS_MeshPrsBuilder::AddVolumePrs (const Handle(MeshVS_HArray1OfSequenceOfInteger)& theTopo, |
822 | const TColStd_Array1OfReal& theNodes, |
823 | const Standard_Integer theNbNodes, |
824 | const Handle(Graphic3d_ArrayOfPrimitives)& theArray, |
825 | const Standard_Boolean theIsShaded, |
826 | const Standard_Boolean theIsShrinked, |
827 | const Standard_Boolean theIsSelected, |
828 | const Standard_Real theShrinkCoef) |
7fd59977 |
829 | { |
37ac4a67 |
830 | Standard_Real aCenter[] = { 0.0, 0.0, 0.0 }; |
7fd59977 |
831 | |
37ac4a67 |
832 | Standard_Integer aLow = theNodes.Lower(); |
833 | |
834 | if (theTopo.IsNull() || theArray.IsNull()) |
7fd59977 |
835 | return; |
836 | |
37ac4a67 |
837 | if (theIsShrinked) |
7fd59977 |
838 | { |
37ac4a67 |
839 | for (Standard_Integer aNodeIdx = 0; aNodeIdx < 3 * theNbNodes; ++aNodeIdx) |
840 | { |
841 | aCenter[aNodeIdx % 3] += theNodes.Value (aLow + aNodeIdx); |
842 | } |
7fd59977 |
843 | |
37ac4a67 |
844 | aCenter[0] /= theNbNodes; |
845 | aCenter[1] /= theNbNodes; |
846 | aCenter[2] /= theNbNodes; |
7fd59977 |
847 | } |
848 | |
37ac4a67 |
849 | Standard_Boolean aIsPolygons = theArray->IsKind (STANDARD_TYPE (Graphic3d_ArrayOfTriangles)); |
7fd59977 |
850 | |
37ac4a67 |
851 | if (aIsPolygons) |
852 | { |
853 | for (Standard_Integer aFaceIdx = theTopo->Lower(), topoup = theTopo->Upper(); aFaceIdx <= topoup; ++aFaceIdx) |
7fd59977 |
854 | { |
37ac4a67 |
855 | const TColStd_SequenceOfInteger& aFaceNodes = theTopo->Value (aFaceIdx); |
856 | const Standard_Integer aNbPolyNodes = aFaceNodes.Length(); |
7fd59977 |
857 | |
37ac4a67 |
858 | Standard_Real* aPolyNodesBuf = (Standard_Real*) alloca ((3 * aNbPolyNodes + 1) * sizeof (Standard_Real)); |
859 | TColStd_Array1OfReal aPolyNodes (*aPolyNodesBuf, 0, 3 * aNbPolyNodes); |
860 | |
861 | for (Standard_Integer aNodeIdx = 0; aNodeIdx < aNbPolyNodes; ++aNodeIdx) |
7fd59977 |
862 | { |
37ac4a67 |
863 | Standard_Integer anIdx = aFaceNodes.Value (aNodeIdx + 1); |
864 | |
865 | Standard_Real aX = theNodes.Value (aLow + 3 * anIdx + 0); |
866 | Standard_Real aY = theNodes.Value (aLow + 3 * anIdx + 1); |
867 | Standard_Real aZ = theNodes.Value (aLow + 3 * anIdx + 2); |
868 | |
869 | if (theIsShrinked) |
870 | { |
871 | aX = aCenter[0] + theShrinkCoef * (aX - aCenter[0]); |
872 | aY = aCenter[1] + theShrinkCoef * (aY - aCenter[1]); |
873 | aZ = aCenter[2] + theShrinkCoef * (aZ - aCenter[2]); |
7fd59977 |
874 | } |
875 | |
37ac4a67 |
876 | aPolyNodes.SetValue (3 * aNodeIdx + 1, aX); |
877 | aPolyNodes.SetValue (3 * aNodeIdx + 2, aY); |
878 | aPolyNodes.SetValue (3 * aNodeIdx + 3, aZ); |
7fd59977 |
879 | } |
37ac4a67 |
880 | |
881 | gp_Vec aNorm; |
7fd59977 |
882 | |
37ac4a67 |
883 | if (theIsShaded) |
7fd59977 |
884 | { |
37ac4a67 |
885 | aPolyNodes.SetValue (0, aNbPolyNodes); |
886 | |
887 | if (!MeshVS_Tool::GetAverageNormal (aPolyNodes, aNorm)) |
888 | { |
889 | aNorm.SetCoord (0.0, 0.0, 1.0); |
890 | } |
891 | } |
7fd59977 |
892 | |
37ac4a67 |
893 | for (Standard_Integer aNodeIdx = 0; aNodeIdx < aNbPolyNodes - 2; ++aNodeIdx) // triangulate polygon |
894 | { |
895 | for (Standard_Integer aSubIdx = 0; aSubIdx < 3; ++aSubIdx) // generate sub-triangle |
7fd59977 |
896 | { |
37ac4a67 |
897 | if (theIsShaded) |
898 | { |
899 | theArray->AddVertex (aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 1), |
900 | aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 2), |
901 | aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 3), |
902 | aNorm.X(), |
903 | aNorm.Y(), |
904 | aNorm.Z()); |
905 | } |
906 | else |
907 | { |
908 | theArray->AddVertex (aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 1), |
909 | aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 2), |
910 | aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 3)); |
911 | } |
7fd59977 |
912 | } |
7fd59977 |
913 | } |
914 | } |
915 | } |
37ac4a67 |
916 | else if (theIsSelected) |
7fd59977 |
917 | { |
37ac4a67 |
918 | for (Standard_Integer aFaceIdx = theTopo->Lower(), topoup = theTopo->Upper(); aFaceIdx <= topoup; ++aFaceIdx) |
7fd59977 |
919 | { |
37ac4a67 |
920 | const TColStd_SequenceOfInteger& aFaceNodes = theTopo->Value (aFaceIdx); |
921 | |
922 | Standard_Real aFaceCenter[] = { 0.0, 0.0, 0.0 }; |
923 | |
924 | for (Standard_Integer aNodeIdx = 1; aNodeIdx <= aFaceNodes.Length(); ++aNodeIdx) |
7fd59977 |
925 | { |
37ac4a67 |
926 | for (Standard_Integer aAxisIdx = 0; aAxisIdx < 3; ++aAxisIdx) |
927 | { |
928 | aFaceCenter[aAxisIdx] += theNodes.Value (aLow + 3 * aFaceNodes.Value (aNodeIdx) + aAxisIdx); |
929 | } |
7fd59977 |
930 | } |
7fd59977 |
931 | |
37ac4a67 |
932 | aFaceCenter[0] /= aFaceNodes.Length(); |
933 | aFaceCenter[1] /= aFaceNodes.Length(); |
934 | aFaceCenter[2] /= aFaceNodes.Length(); |
935 | |
936 | for (Standard_Integer aNodeIdx = 0, aNbNodes = aFaceNodes.Length(); aNodeIdx < aNbNodes; ++aNodeIdx) |
7fd59977 |
937 | { |
37ac4a67 |
938 | for (Standard_Integer aSubIdx = 0; aSubIdx < 2; ++aSubIdx) // add segment |
939 | { |
940 | Standard_Integer anIdx = aFaceNodes.Value ((aNodeIdx + aSubIdx) % aNbNodes + 1); |
941 | |
942 | Standard_Real aX = theNodes.Value (aLow + 3 * anIdx + 0); |
943 | Standard_Real aY = theNodes.Value (aLow + 3 * anIdx + 1); |
944 | Standard_Real aZ = theNodes.Value (aLow + 3 * anIdx + 2); |
945 | |
946 | theArray->AddVertex (aFaceCenter[0] + theShrinkCoef * (aX - aFaceCenter[0]), |
947 | aFaceCenter[1] + theShrinkCoef * (aY - aFaceCenter[1]), |
948 | aFaceCenter[2] + theShrinkCoef * (aZ - aFaceCenter[2])); |
949 | } |
7fd59977 |
950 | } |
951 | } |
952 | } |
953 | else |
954 | { |
37ac4a67 |
955 | // Find all pairs of nodes (edges) to draw (will be drawn only once) |
956 | NCollection_Map<MeshVS_NodePair, MeshVS_SymmetricPairHasher> aEdgeMap; |
7fd59977 |
957 | |
37ac4a67 |
958 | for (Standard_Integer aFaceIdx = theTopo->Lower(), topoup = theTopo->Upper(); aFaceIdx <= topoup; ++aFaceIdx) |
7fd59977 |
959 | { |
37ac4a67 |
960 | const TColStd_SequenceOfInteger& aFaceNodes = theTopo->Value (aFaceIdx); |
961 | |
962 | for (Standard_Integer aNodeIdx = 0, aNbNodes = aFaceNodes.Length(); aNodeIdx < aNbNodes; ++aNodeIdx) |
7fd59977 |
963 | { |
37ac4a67 |
964 | const Standard_Integer aNextIdx = (aNodeIdx + 1) % aNbNodes; |
7fd59977 |
965 | |
37ac4a67 |
966 | aEdgeMap.Add (MeshVS_NodePair (aFaceNodes.Value (aNodeIdx + 1), |
967 | aFaceNodes.Value (aNextIdx + 1))); |
7fd59977 |
968 | } |
969 | } |
970 | |
37ac4a67 |
971 | // Draw edges |
972 | for(NCollection_Map<MeshVS_NodePair, MeshVS_SymmetricPairHasher>::Iterator anIt (aEdgeMap); anIt.More(); anIt.Next()) |
7fd59977 |
973 | { |
37ac4a67 |
974 | const Standard_Integer anIdx1 = aLow + 3 * anIt.Key().first; |
975 | const Standard_Integer anIdx2 = aLow + 3 * anIt.Key().second; |
976 | |
977 | Standard_Real aX[] = { theNodes.Value (anIdx1 + 0), theNodes.Value (anIdx2 + 0) }; |
978 | Standard_Real aY[] = { theNodes.Value (anIdx1 + 1), theNodes.Value (anIdx2 + 1) }; |
979 | Standard_Real aZ[] = { theNodes.Value (anIdx1 + 2), theNodes.Value (anIdx2 + 2) }; |
980 | |
981 | if (theIsShrinked) |
982 | { |
983 | for (Standard_Integer anAxisIdx = 0; anAxisIdx < 2; ++anAxisIdx) |
7fd59977 |
984 | { |
37ac4a67 |
985 | aX[anAxisIdx] = aCenter[0] + theShrinkCoef * (aX[anAxisIdx] - aCenter[0]); |
986 | aY[anAxisIdx] = aCenter[1] + theShrinkCoef * (aY[anAxisIdx] - aCenter[1]); |
987 | aZ[anAxisIdx] = aCenter[2] + theShrinkCoef * (aZ[anAxisIdx] - aCenter[2]); |
7fd59977 |
988 | } |
37ac4a67 |
989 | } |
7fd59977 |
990 | |
37ac4a67 |
991 | theArray->AddVertex (aX[0], aY[0], aZ[0]); |
992 | theArray->AddVertex (aX[1], aY[1], aZ[1]); |
7fd59977 |
993 | } |
994 | } |
995 | } |
996 | |
997 | //================================================================ |
998 | // Function : HowManyPrimitives |
999 | // Purpose : |
1000 | //================================================================ |
1001 | void MeshVS_MeshPrsBuilder::HowManyPrimitives (const Handle(MeshVS_HArray1OfSequenceOfInteger)& Topo, |
1002 | const Standard_Boolean AsPolygons, |
1003 | const Standard_Boolean IsSelect, |
1004 | const Standard_Integer NbNodes, |
1005 | Standard_Integer& Vertices, |
1006 | Standard_Integer& Bounds) |
1007 | { |
eafb234b |
1008 | if( !Topo.IsNull() ) { |
7fd59977 |
1009 | if( AsPolygons || IsSelect ) |
1010 | { |
1011 | Standard_Integer B = Topo->Upper()-Topo->Lower()+1; |
1012 | Bounds += B; |
1013 | for( Standard_Integer i=Topo->Lower(), n=Topo->Upper(); i<=n; i++ ) |
1014 | Vertices += Topo->Value( i ).Length(); |
1015 | |
1016 | if( IsSelect ) |
1017 | Vertices+=B; |
1018 | } |
1019 | else |
1020 | { |
1021 | Standard_Integer F = Topo->Upper()-Topo->Lower()+1, |
1022 | E = NbNodes + F - 2; |
1023 | // number of edges is obtained by Euler's expression for polyhedrons |
1024 | |
1025 | Bounds += E; |
1026 | Vertices += 2*E; |
1027 | } |
eafb234b |
1028 | } |
7fd59977 |
1029 | } |
1030 | |
1031 | //================================================================ |
1032 | // Function : DrawArrays |
1033 | // Purpose : |
1034 | //================================================================ |
1035 | void MeshVS_MeshPrsBuilder::DrawArrays( const Handle(Prs3d_Presentation)& Prs, |
37ac4a67 |
1036 | const Handle(Graphic3d_ArrayOfPrimitives)& thePolygons, |
1037 | const Handle(Graphic3d_ArrayOfPrimitives)& theLines, |
1038 | const Handle(Graphic3d_ArrayOfPrimitives)& theLinkLines, |
1039 | const Handle(Graphic3d_ArrayOfPrimitives)& theVolumesInShad, |
7fd59977 |
1040 | const Standard_Boolean IsPolygonsEdgesOff, |
1041 | const Standard_Boolean IsSelected, |
1042 | const Handle(Graphic3d_AspectFillArea3d)& theFillAsp, |
1043 | const Handle(Graphic3d_AspectLine3d)& theLineAsp ) const |
1044 | { |
1045 | if ( theFillAsp.IsNull() ) |
1046 | return; |
1047 | |
1048 | Standard_Boolean IsFacePolygons = ( !thePolygons.IsNull() && thePolygons->ItemNumber() > 0 ), |
1049 | IsVolumePolygons = ( !theVolumesInShad.IsNull() && theVolumesInShad->ItemNumber() > 0 ), |
1050 | IsPolygons = IsFacePolygons || IsVolumePolygons, |
1051 | IsPolylines = ( !theLines.IsNull() && theLines->ItemNumber() > 0 ), |
1052 | IsLinkPolylines = ( !theLinkLines.IsNull() && theLinkLines->ItemNumber() > 0 ); |
1053 | |
1054 | Aspect_InteriorStyle aStyle; |
1055 | Quantity_Color anIntColor, aBackColor, anEdgeColor; |
1056 | Aspect_TypeOfLine aType; |
1057 | Standard_Real aWidth; |
1058 | |
1059 | theFillAsp->Values( aStyle, anIntColor, aBackColor, anEdgeColor, aType, aWidth ); |
1060 | |
c3715b74 |
1061 | Standard_Boolean isSupressBackFaces = Standard_False; |
1062 | Handle(MeshVS_Drawer) aDrawer = GetDrawer(); |
1063 | if (!aDrawer.IsNull()) |
1064 | { |
1065 | aDrawer->GetBoolean (MeshVS_DA_SupressBackFaces, isSupressBackFaces); |
1066 | } |
1067 | |
7fd59977 |
1068 | if ( IsPolygons && theFillAsp->FrontMaterial().Transparency()<0.01 ) |
1069 | { |
1070 | Prs3d_Root::NewGroup ( Prs ); |
1071 | Handle (Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup ( Prs ); |
1072 | |
1073 | //if ( IsPolygonsEdgesOff ) |
1074 | theFillAsp->SetEdgeOff (); |
1075 | //else |
1076 | // theFillAsp->SetEdgeOn (); |
1077 | |
1078 | if( anIntColor!=aBackColor ) |
1079 | theFillAsp->SetDistinguishOn(); |
1080 | else |
1081 | theFillAsp->SetDistinguishOff(); |
1082 | |
c3715b74 |
1083 | aGroup->SetClosed (isSupressBackFaces); |
1084 | Handle(Graphic3d_AspectFillArea3d) aFillAsp = new Graphic3d_AspectFillArea3d (*(theFillAsp.operator->())); |
1085 | if (isSupressBackFaces) |
1086 | { |
1087 | aFillAsp->SuppressBackFace(); |
1088 | } |
1089 | aGroup->SetPrimitivesAspect (aFillAsp); |
1090 | |
7fd59977 |
1091 | if( IsFacePolygons ) |
1092 | { |
7fd59977 |
1093 | aGroup->AddPrimitiveArray ( thePolygons ); |
7fd59977 |
1094 | } |
1095 | |
1096 | if( IsVolumePolygons ) |
1097 | { |
7fd59977 |
1098 | aGroup->AddPrimitiveArray ( theVolumesInShad ); |
7fd59977 |
1099 | } |
1100 | } |
1101 | |
1102 | if ( IsPolylines && !IsPolygonsEdgesOff ) |
1103 | { |
1104 | Prs3d_Root::NewGroup ( Prs ); |
1105 | Handle (Graphic3d_Group) aLGroup = Prs3d_Root::CurrentGroup ( Prs ); |
1106 | |
1107 | theFillAsp->SetEdgeOff(); |
1108 | if ( IsSelected ) |
1109 | aLGroup->SetPrimitivesAspect ( theLineAsp ); |
1110 | else |
1111 | { |
1112 | aLGroup->SetPrimitivesAspect ( theFillAsp ); |
1113 | aLGroup->SetPrimitivesAspect ( new Graphic3d_AspectLine3d |
1114 | ( anEdgeColor, Aspect_TOL_SOLID, aWidth ) ); |
1115 | } |
7fd59977 |
1116 | aLGroup->AddPrimitiveArray ( theLines ); |
7fd59977 |
1117 | theFillAsp->SetEdgeOn(); |
1118 | } |
1119 | |
1120 | if ( IsLinkPolylines ) |
1121 | { |
1122 | Prs3d_Root::NewGroup ( Prs ); |
1123 | Handle (Graphic3d_Group) aBeamGroup = Prs3d_Root::CurrentGroup ( Prs ); |
1124 | |
1125 | theFillAsp->SetEdgeOff(); |
1126 | if ( !IsSelected ) |
1127 | aBeamGroup->SetPrimitivesAspect ( theFillAsp ); |
1128 | aBeamGroup->SetPrimitivesAspect ( theLineAsp ); |
7fd59977 |
1129 | aBeamGroup->AddPrimitiveArray ( theLinkLines ); |
7fd59977 |
1130 | theFillAsp->SetEdgeOn(); |
1131 | } |
1132 | |
1133 | if ( IsPolygons && theFillAsp->FrontMaterial().Transparency()>=0.01 ) |
1134 | { |
1135 | Prs3d_Root::NewGroup ( Prs ); |
1136 | Handle (Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup ( Prs ); |
1137 | |
1138 | //if ( IsPolygonsEdgesOff ) |
1139 | theFillAsp->SetEdgeOff (); |
1140 | //else |
1141 | // theFillAsp->SetEdgeOn (); |
1142 | |
1143 | if( anIntColor!=aBackColor ) |
1144 | theFillAsp->SetDistinguishOn(); |
1145 | else |
1146 | theFillAsp->SetDistinguishOff(); |
1147 | |
c3715b74 |
1148 | aGroup->SetClosed (isSupressBackFaces); |
1149 | Handle(Graphic3d_AspectFillArea3d) aFillAsp = new Graphic3d_AspectFillArea3d (*(theFillAsp.operator->())); |
1150 | if (isSupressBackFaces) |
1151 | { |
1152 | aFillAsp->SuppressBackFace(); |
1153 | } |
1154 | aGroup->SetPrimitivesAspect (aFillAsp); |
1155 | |
7fd59977 |
1156 | if( IsFacePolygons ) |
1157 | { |
7fd59977 |
1158 | aGroup->AddPrimitiveArray ( thePolygons ); |
7fd59977 |
1159 | } |
1160 | |
1161 | if( IsVolumePolygons ) |
1162 | { |
7fd59977 |
1163 | aGroup->AddPrimitiveArray ( theVolumesInShad ); |
7fd59977 |
1164 | } |
1165 | } |
1166 | } |
1167 | |
1168 | //================================================================ |
1169 | // Function : CalculateCenter |
1170 | // Purpose : |
1171 | //================================================================ |
1172 | void MeshVS_MeshPrsBuilder::CalculateCenter (const TColStd_Array1OfReal& theCoords, |
1173 | const Standard_Integer NbNodes, |
1174 | Standard_Real &xG, |
1175 | Standard_Real &yG, |
1176 | Standard_Real &zG) |
1177 | { |
1178 | xG = yG = zG = 0; |
1179 | if ( NbNodes < 4 ) |
1180 | { |
1181 | for ( Standard_Integer k=1; k<=NbNodes; k++) |
1182 | { |
1183 | xG += theCoords(3*k-2); |
1184 | yG += theCoords(3*k-1); |
1185 | zG += theCoords(3*k); |
1186 | } |
1187 | xG /= Standard_Real(NbNodes); |
1188 | yG /= Standard_Real(NbNodes); |
1189 | zG /= Standard_Real(NbNodes); |
1190 | } |
1191 | else |
1192 | { |
1193 | Standard_Integer a = 1, b = 3; |
1194 | xG = ( theCoords( 3*a-2 ) + theCoords( 3*b-2 ) ) / 2.0; |
1195 | yG = ( theCoords( 3*a-1 ) + theCoords( 3*b-1 ) ) / 2.0; |
1196 | zG = ( theCoords( 3*a ) + theCoords( 3*b ) ) / 2.0; |
1197 | } |
1198 | } |