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