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