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 | |
335 | Quantity_Color anOldEdgeColor; |
37ac4a67 |
336 | Quantity_Color anEdgeColor; |
337 | Quantity_Color anIntColor; |
7fd59977 |
338 | Aspect_InteriorStyle anIntType; |
7fd59977 |
339 | Aspect_TypeOfLine aLine; |
340 | Standard_Real aWidth; |
341 | |
37ac4a67 |
342 | aFill->Values (anIntType, anIntColor, anEdgeColor, aLine, aWidth); |
7fd59977 |
343 | |
344 | MeshVS_MapOfTwoNodes aLinkNodes; |
37ac4a67 |
345 | |
346 | // Forbid drawings of edges which overlap with some links |
347 | if (showEdges && IsOverlapControl) |
348 | { |
349 | for (it.Reset(); it.More(); it.Next()) |
7fd59977 |
350 | { |
37ac4a67 |
351 | if (aSource->GetGeomType (it.Key(), Standard_True, aType) && aType == MeshVS_ET_Link) |
7fd59977 |
352 | { |
37ac4a67 |
353 | Standard_Integer aNbNodes; |
354 | |
355 | if (aSource->GetNodesByElement (it.Key(), aNodes, aNbNodes) && aNbNodes == 2) |
7fd59977 |
356 | { |
37ac4a67 |
357 | aLinkNodes.Add (MeshVS_TwoNodes (aNodes(1), aNodes(2))); |
7fd59977 |
358 | } |
359 | } |
360 | } |
37ac4a67 |
361 | } |
362 | |
363 | NCollection_Map<MeshVS_NodePair, MeshVS_SymmetricPairHasher> aSegmentMap; |
7fd59977 |
364 | |
37ac4a67 |
365 | for (it.Reset(); it.More(); it.Next()) |
7fd59977 |
366 | { |
37ac4a67 |
367 | const Standard_Integer aKey = it.Key(); |
368 | |
369 | Standard_Integer NbNodes; |
370 | if (!aSource->GetGeom (aKey, Standard_True, aCoords, NbNodes, aType)) |
371 | continue; |
7fd59977 |
372 | |
37ac4a67 |
373 | if (!aSource->GetNodesByElement (aKey, aNodes, NbNodes)) |
7fd59977 |
374 | continue; |
375 | |
37ac4a67 |
376 | switch (aType) |
7fd59977 |
377 | { |
37ac4a67 |
378 | case MeshVS_ET_Volume: |
379 | { |
380 | if (IsExcludingOn()) |
7fd59977 |
381 | IDsToExclude.Add (aKey); |
37ac4a67 |
382 | |
383 | if (aSource->Get3DGeom (aKey, NbNodes, aTopo)) |
7fd59977 |
384 | { |
37ac4a67 |
385 | // Add wire-frame presentation (draw edges for shading mode as well) |
386 | if (showEdges) |
387 | { |
388 | AddVolumePrs (aTopo, aCoords, NbNodes, |
389 | aEdgeSegments, IsReflect, IsShrink, HasSelectFlag, aShrinkCoef); |
390 | } |
391 | |
392 | // Add shading presentation |
393 | if ((IsShading || IsShrink) && !HasSelectFlag) |
394 | { |
395 | AddVolumePrs (aTopo, aCoords, NbNodes, |
396 | aVolmTriangles, IsReflect, IsShrink, HasSelectFlag, aShrinkCoef); |
397 | } |
7fd59977 |
398 | } |
37ac4a67 |
399 | } |
400 | break; |
7fd59977 |
401 | |
37ac4a67 |
402 | case MeshVS_ET_Link: |
403 | { |
404 | if (IsExcludingOn()) |
7fd59977 |
405 | IDsToExclude.Add (aKey); |
7fd59977 |
406 | |
37ac4a67 |
407 | if (showEdges) |
7fd59977 |
408 | { |
37ac4a67 |
409 | AddLinkPrs (aCoords, aLinkSegments, IsShrink || HasSelectFlag, aShrinkCoef); |
410 | } |
411 | } |
412 | break; |
7fd59977 |
413 | |
37ac4a67 |
414 | case MeshVS_ET_Face: |
415 | { |
416 | if (IsExcludingOn()) |
417 | IDsToExclude.Add (aKey); |
418 | |
419 | if (showEdges && IsOverlapControl) |
420 | { |
7fd59977 |
421 | Standard_Integer Last = 0; |
37ac4a67 |
422 | |
423 | MeshVS_TwoNodes aTwoNodes (aNodes (1)); |
424 | |
425 | for (Standard_Integer i = 1; i <= NbNodes; ++i) |
7fd59977 |
426 | { |
37ac4a67 |
427 | if (i > 1) |
7fd59977 |
428 | aTwoNodes.First = aTwoNodes.Second; |
429 | |
37ac4a67 |
430 | aTwoNodes.Second = (i < NbNodes) ? aNodes (i+1) : aNodes (1); |
431 | |
432 | if (aLinkNodes.Contains (aTwoNodes)) |
433 | { |
434 | for (Standard_Integer aNodeIdx = Last + 1; aNodeIdx < i; ++aNodeIdx) |
7fd59977 |
435 | { |
37ac4a67 |
436 | const Standard_Integer aNextIdx = aNodeIdx + 1; |
437 | |
438 | aEdgeSegments->AddVertex ( |
439 | aCoords (3 * aNodeIdx - 2), aCoords (3 * aNodeIdx - 1), aCoords (3 * aNodeIdx)); |
440 | aEdgeSegments->AddVertex ( |
441 | aCoords (3 * aNextIdx - 2), aCoords (3 * aNextIdx - 1), aCoords (3 * aNextIdx)); |
7fd59977 |
442 | } |
37ac4a67 |
443 | |
444 | Last = i; |
445 | } |
7fd59977 |
446 | } |
37ac4a67 |
447 | |
448 | if (NbNodes - Last > 0) |
7fd59977 |
449 | { |
37ac4a67 |
450 | for (Standard_Integer aNodeIdx = Last; aNodeIdx < NbNodes; ++aNodeIdx) |
451 | { |
452 | const Standard_Integer aNextIdx = (aNodeIdx + 1) % NbNodes; |
453 | |
454 | const MeshVS_NodePair aSegment (aNodes (aNodeIdx + 1), |
455 | aNodes (aNextIdx + 1)); |
456 | |
457 | if (!aSegmentMap.Contains (aSegment)) |
458 | { |
459 | aEdgeSegments->AddVertex (aCoords (3 * aNodeIdx + 1), |
460 | aCoords (3 * aNodeIdx + 2), |
461 | aCoords (3 * aNodeIdx + 3)); |
7fd59977 |
462 | |
37ac4a67 |
463 | aEdgeSegments->AddVertex (aCoords (3 * aNextIdx + 1), |
464 | aCoords (3 * aNextIdx + 2), |
465 | aCoords (3 * aNextIdx + 3)); |
466 | |
467 | aSegmentMap.Add (aSegment); |
468 | } |
469 | } |
7fd59977 |
470 | } |
471 | } |
472 | |
37ac4a67 |
473 | if (!IsOverlapControl || IsShading) |
7fd59977 |
474 | { |
37ac4a67 |
475 | if (!IsOverlapControl && showEdges) |
476 | { |
477 | AddFaceWirePrs (aCoords, NbNodes, |
478 | aEdgeSegments, IsShrink || HasSelectFlag, aShrinkCoef); |
479 | } |
480 | |
481 | if ((IsShading || IsShrink) && !HasSelectFlag) |
482 | { |
483 | AddFaceSolidPrs (aKey, aCoords, NbNodes, maxnodes, aFaceTriangles, IsReflect, |
484 | IsShrink || HasSelectFlag, aShrinkCoef, IsMeshSmoothShading); |
485 | } |
7fd59977 |
486 | } |
37ac4a67 |
487 | } |
488 | break; |
7fd59977 |
489 | |
490 | default: |
37ac4a67 |
491 | { |
492 | aCustomElements.Add (aKey); |
493 | } |
7fd59977 |
494 | } |
495 | } |
496 | |
37ac4a67 |
497 | if (IsShrink) |
7fd59977 |
498 | { |
499 | anOldEdgeColor = anEdgeColor; |
37ac4a67 |
500 | aFill->SetEdgeColor (Quantity_NOC_BLACK); |
7fd59977 |
501 | } |
502 | |
37ac4a67 |
503 | //std::cout << "Actual extents: " << std::endl |
504 | // << "Face tris: " << aFaceTriangles->ItemNumber() << " from " << aNbFacePrimitives << std::endl |
505 | // << "Volm tris: " << aVolmTriangles->ItemNumber() << " from " << aNbVolmPrimitives << std::endl |
506 | // << "Face segs: " << aEdgeSegments->ItemNumber() << " from " << aNbEdgePrimitives << std::endl |
507 | // << "Link segs: " << aLinkSegments->ItemNumber() << " from " << aNbLinkPrimitives << std::endl; |
508 | |
509 | DrawArrays ( Prs, aFaceTriangles, aEdgeSegments, aLinkSegments, aVolmTriangles, |
7fd59977 |
510 | !showEdges, HasSelectFlag, aFill, aBeam ); |
511 | |
512 | if ( !aCustomElements.IsEmpty() ) |
513 | CustomBuild ( Prs, aCustomElements, IDsToExclude, DisplayMode ); |
514 | |
515 | if( IsShrink ) |
516 | aFill->SetEdgeColor( anOldEdgeColor ); |
517 | } |
518 | |
519 | //================================================================ |
520 | // Function : BuildHilightPrs |
521 | // Purpose : |
522 | //================================================================ |
523 | void MeshVS_MeshPrsBuilder::BuildHilightPrs ( const Handle(Prs3d_Presentation)& Prs, |
524 | const TColStd_PackedMapOfInteger& IDs, |
525 | const Standard_Boolean IsElement ) const |
526 | { |
527 | Standard_Integer maxnodes; |
528 | |
529 | Handle (MeshVS_DataSource) aSource = GetDataSource(); |
530 | if ( aSource.IsNull() || IDs.IsEmpty() ) |
531 | return; |
532 | |
533 | Handle( MeshVS_Drawer ) aDrawer = GetDrawer(); |
534 | if ( aDrawer.IsNull() || !aDrawer->GetInteger ( MeshVS_DA_MaxFaceNodes, maxnodes ) || |
535 | maxnodes <= 0 ) |
536 | return; |
537 | |
538 | MeshVS_Buffer aCoordsBuf (3*maxnodes*sizeof(Standard_Real)); |
539 | TColStd_Array1OfReal aCoords (aCoordsBuf, 1, 3*maxnodes); |
540 | |
541 | Graphic3d_MaterialAspect AMat; |
542 | aDrawer->GetMaterial ( MeshVS_DA_FrontMaterial, AMat ); |
543 | AMat.SetReflectionModeOff(Graphic3d_TOR_AMBIENT); |
544 | AMat.SetReflectionModeOff(Graphic3d_TOR_DIFFUSE); |
545 | AMat.SetReflectionModeOff(Graphic3d_TOR_SPECULAR); |
546 | AMat.SetReflectionModeOff(Graphic3d_TOR_EMISSION); |
547 | |
548 | Handle( Graphic3d_AspectFillArea3d ) aFill = MeshVS_Tool::CreateAspectFillArea3d( GetDrawer(), AMat ); |
549 | Handle( Graphic3d_AspectLine3d ) aBeam = MeshVS_Tool::CreateAspectLine3d( GetDrawer() ); |
550 | Handle( Graphic3d_AspectMarker3d ) aNodeMark = MeshVS_Tool::CreateAspectMarker3d( GetDrawer() ); |
551 | |
552 | // Hilight one element or node |
553 | TColStd_MapIteratorOfPackedMapOfInteger it (IDs); |
554 | Standard_Integer ID = it.Key(), NbNodes; |
555 | MeshVS_EntityType aType; |
556 | |
557 | if ( !aSource->GetGeom ( ID, IsElement, aCoords, NbNodes, aType ) ) |
558 | return; |
559 | |
560 | Prs3d_Root::NewGroup ( Prs ); |
561 | Handle (Graphic3d_Group) aHilightGroup = Prs3d_Root::CurrentGroup ( Prs ); |
562 | |
563 | switch ( aType ) |
564 | { |
565 | case MeshVS_ET_Node : |
566 | { |
a577aaab |
567 | aHilightGroup->SetPrimitivesAspect (aNodeMark); |
568 | Handle(Graphic3d_ArrayOfPoints) anArrayOfPoints = new Graphic3d_ArrayOfPoints (1); |
569 | anArrayOfPoints->AddVertex (aCoords(1), aCoords(2), aCoords(3)); |
570 | aHilightGroup->AddPrimitiveArray (anArrayOfPoints); |
7fd59977 |
571 | } |
572 | break; |
573 | |
574 | case MeshVS_ET_Link: |
575 | { |
576 | aHilightGroup->SetPrimitivesAspect ( aBeam ); |
b8ddfc2f |
577 | Handle(Graphic3d_ArrayOfSegments) aPrims = new Graphic3d_ArrayOfSegments(2); |
578 | aPrims->AddVertex(aCoords(1),aCoords(2),aCoords(3)); |
579 | aPrims->AddVertex(aCoords(4),aCoords(5),aCoords(6)); |
580 | aHilightGroup->AddPrimitiveArray(aPrims); |
7fd59977 |
581 | } |
582 | break; |
583 | |
584 | case MeshVS_ET_Face: |
585 | if ( NbNodes > 0 ) |
586 | { |
7fd59977 |
587 | aHilightGroup->SetPrimitivesAspect ( aFill ); |
b8ddfc2f |
588 | Handle(Graphic3d_ArrayOfPolygons) aPrims = new Graphic3d_ArrayOfPolygons(NbNodes); |
7fd59977 |
589 | for ( Standard_Integer k=1; k<=NbNodes; k++) |
b8ddfc2f |
590 | aPrims->AddVertex(aCoords(3*k-2),aCoords(3*k-1),aCoords(3*k)); |
591 | aHilightGroup->AddPrimitiveArray(aPrims); |
7fd59977 |
592 | } |
593 | break; |
594 | |
595 | case MeshVS_ET_Volume: |
596 | if( NbNodes > 0 ) |
597 | { |
598 | Handle( MeshVS_HArray1OfSequenceOfInteger ) aTopo; |
599 | |
600 | aHilightGroup->SetPrimitivesAspect ( aFill ); |
601 | |
602 | if( aSource->Get3DGeom( ID, NbNodes, aTopo ) ) |
603 | { |
b8ddfc2f |
604 | const Standard_Integer up = aTopo->Upper(); |
605 | const Standard_Integer lo = aTopo->Lower(); |
606 | Standard_Integer nbnodes = 0, i, j; |
607 | for( i=lo; i<=up; i++ ) |
608 | nbnodes += aTopo->Value( i ).Length(); |
609 | |
610 | Handle(Graphic3d_ArrayOfPolygons) aPrims = new Graphic3d_ArrayOfPolygons(nbnodes,aTopo->Length()); |
611 | for( i=lo; i<=up; i++ ) |
7fd59977 |
612 | { |
613 | const TColStd_SequenceOfInteger& aSeq = aTopo->Value( i ); |
b8ddfc2f |
614 | const Standard_Integer m = aSeq.Length(); |
615 | aPrims->AddBound(m); |
7fd59977 |
616 | for( j=1; j<=m; j++ ) |
617 | { |
b8ddfc2f |
618 | const Standard_Integer ind = 3*aSeq.Value( j ); |
619 | aPrims->AddVertex(aCoords(ind+1),aCoords(ind+2),aCoords(ind+3)); |
7fd59977 |
620 | } |
7fd59977 |
621 | } |
b8ddfc2f |
622 | aHilightGroup->AddPrimitiveArray(aPrims); |
7fd59977 |
623 | } |
624 | } |
625 | break; |
626 | |
627 | default: |
628 | { |
629 | TColStd_PackedMapOfInteger tmp; |
630 | CustomBuild ( Prs, IDs, tmp, MeshVS_DMF_HilightPrs ); |
631 | } |
632 | break; |
633 | } |
634 | } |
635 | |
636 | //================================================================ |
637 | // Function : AddLinkPrs |
638 | // Purpose : |
639 | //================================================================ |
37ac4a67 |
640 | void MeshVS_MeshPrsBuilder::AddLinkPrs (const TColStd_Array1OfReal& theCoords, |
641 | const Handle(Graphic3d_ArrayOfSegments)& theSegments, |
642 | const Standard_Boolean theIsShrinked, |
643 | const Standard_Real theShrinkCoef) const |
7fd59977 |
644 | { |
37ac4a67 |
645 | Standard_Real aX1 = theCoords (1); |
646 | Standard_Real aY1 = theCoords (2); |
647 | Standard_Real aZ1 = theCoords (3); |
648 | Standard_Real aX2 = theCoords (4); |
649 | Standard_Real aY2 = theCoords (5); |
650 | Standard_Real aZ2 = theCoords (6); |
651 | |
652 | if (theIsShrinked) |
7fd59977 |
653 | { |
37ac4a67 |
654 | const Standard_Real xG = (aX1 + aX2) * 0.5; |
655 | const Standard_Real yG = (aY1 + aY2) * 0.5; |
656 | const Standard_Real zG = (aZ1 + aZ2) * 0.5; |
657 | |
658 | aX1 = (aX1 - xG) * theShrinkCoef + xG; |
659 | aY1 = (aY1 - yG) * theShrinkCoef + yG; |
660 | aZ1 = (aZ1 - zG) * theShrinkCoef + zG; |
661 | |
662 | aX2 = 2.0 * xG - aX1; |
663 | aY2 = 2.0 * yG - aY1; |
664 | aZ2 = 2.0 * zG - aZ1; |
7fd59977 |
665 | } |
37ac4a67 |
666 | |
667 | theSegments->AddVertex (aX1, aY1, aZ1); |
668 | theSegments->AddVertex (aX2, aY2, aZ2); |
7fd59977 |
669 | } |
670 | |
671 | //================================================================ |
672 | // Function : AddFaceWirePrs |
673 | // Purpose : |
674 | //================================================================ |
37ac4a67 |
675 | void MeshVS_MeshPrsBuilder::AddFaceWirePrs (const TColStd_Array1OfReal& theCoords, |
676 | const Standard_Integer theNbNodes, |
677 | const Handle(Graphic3d_ArrayOfSegments)& theSegments, |
678 | const Standard_Boolean theIsShrinked, |
679 | const Standard_Real theShrinkingCoef) const |
7fd59977 |
680 | { |
37ac4a67 |
681 | Standard_Real aCenterX = 0.0; |
682 | Standard_Real aCenterY = 0.0; |
683 | Standard_Real aCenterZ = 0.0; |
7fd59977 |
684 | |
37ac4a67 |
685 | if (theIsShrinked) |
7fd59977 |
686 | { |
37ac4a67 |
687 | CalculateCenter (theCoords, theNbNodes, aCenterX, aCenterY, aCenterZ); |
688 | } |
689 | |
690 | NCollection_Vector<gp_XYZ> aNodes (theNbNodes); |
691 | |
692 | for (Standard_Integer aNodeIdx = 0; aNodeIdx < theNbNodes; ++aNodeIdx) |
693 | { |
694 | gp_XYZ aPnt (theCoords (3 * aNodeIdx + 1), |
695 | theCoords (3 * aNodeIdx + 2), |
696 | theCoords (3 * aNodeIdx + 3)); |
697 | |
698 | if (theIsShrinked) |
7fd59977 |
699 | { |
37ac4a67 |
700 | aPnt.SetX ((aPnt.X() - aCenterX) * theShrinkingCoef + aCenterX); |
701 | aPnt.SetY ((aPnt.Y() - aCenterY) * theShrinkingCoef + aCenterY); |
702 | aPnt.SetZ ((aPnt.Z() - aCenterZ) * theShrinkingCoef + aCenterZ); |
7fd59977 |
703 | } |
37ac4a67 |
704 | |
705 | aNodes.Append (aPnt); |
706 | } |
707 | |
708 | for (Standard_Integer aNodeIdx = 0; aNodeIdx < theNbNodes; ++aNodeIdx) |
709 | { |
710 | theSegments->AddVertex (aNodes.Value (aNodeIdx).X(), |
711 | aNodes.Value (aNodeIdx).Y(), |
712 | aNodes.Value (aNodeIdx).Z()); |
713 | |
714 | const Standard_Integer aNextIdx = (aNodeIdx + 1) % theNbNodes; |
715 | |
716 | theSegments->AddVertex (aNodes.Value (aNextIdx).X(), |
717 | aNodes.Value (aNextIdx).Y(), |
718 | aNodes.Value (aNextIdx).Z()); |
7fd59977 |
719 | } |
7fd59977 |
720 | } |
721 | |
722 | //================================================================ |
723 | // Function : AddFaceSolidPrs |
724 | // Purpose : |
725 | //================================================================ |
37ac4a67 |
726 | void MeshVS_MeshPrsBuilder::AddFaceSolidPrs (const Standard_Integer theID, |
727 | const TColStd_Array1OfReal& theCoords, |
728 | const Standard_Integer theNbNodes, |
729 | const Standard_Integer theMaxNodes, |
730 | const Handle(Graphic3d_ArrayOfTriangles)& theTriangles, |
731 | const Standard_Boolean theIsShaded, |
732 | const Standard_Boolean theIsShrinked, |
733 | const Standard_Real theShrinkingCoef, |
734 | const Standard_Boolean theIsSmoothShading) const |
7fd59977 |
735 | { |
37ac4a67 |
736 | Handle(MeshVS_DataSource) aDataSource = myParentMesh->GetDataSource(); |
737 | |
738 | if (aDataSource.IsNull()) |
7fd59977 |
739 | return; |
740 | |
37ac4a67 |
741 | Standard_Real aCenterX = 0.0; |
742 | Standard_Real aCenterY = 0.0; |
743 | Standard_Real aCenterZ = 0.0; |
744 | Standard_Real aNormalX = 0.0; |
745 | Standard_Real aNormalY = 0.0; |
746 | Standard_Real aNormalZ = 0.0; |
7fd59977 |
747 | |
37ac4a67 |
748 | if (theIsShrinked) |
749 | { |
750 | CalculateCenter (theCoords, theNbNodes, aCenterX, aCenterY, aCenterZ); |
751 | } |
7fd59977 |
752 | |
37ac4a67 |
753 | NCollection_Vector<gp_XYZ> aVertexNormals (theMaxNodes); |
754 | |
755 | if (theIsShaded) |
7fd59977 |
756 | { |
37ac4a67 |
757 | if (theIsSmoothShading) |
758 | { |
759 | for (Standard_Integer aNodeIdx = 1; aNodeIdx <= theNbNodes; ++aNodeIdx) |
760 | { |
761 | if (!aDataSource->GetNodeNormal (aNodeIdx, theID, aNormalX, aNormalY, aNormalZ)) |
762 | break; |
763 | |
764 | aVertexNormals.Append (gp_XYZ (aNormalX, aNormalY, aNormalZ)); |
765 | } |
766 | } |
767 | |
768 | if (!theIsSmoothShading || aVertexNormals.Size() != theNbNodes) |
769 | { |
770 | aDataSource->GetNormal (theID, theMaxNodes, aNormalX, aNormalY, aNormalZ); |
771 | } |
7fd59977 |
772 | } |
773 | |
37ac4a67 |
774 | NCollection_Vector<gp_XYZ> aNodes (theMaxNodes); |
775 | |
776 | for (Standard_Integer aNodeIdx = 0; aNodeIdx < theNbNodes; ++aNodeIdx) |
7fd59977 |
777 | { |
37ac4a67 |
778 | gp_XYZ aPnt (theCoords (3 * aNodeIdx + 1), |
779 | theCoords (3 * aNodeIdx + 2), |
780 | theCoords (3 * aNodeIdx + 3)); |
781 | |
782 | if (theIsShrinked) |
7fd59977 |
783 | { |
37ac4a67 |
784 | aPnt.SetX ((aPnt.X() - aCenterX) * theShrinkingCoef + aCenterX); |
785 | aPnt.SetY ((aPnt.Y() - aCenterY) * theShrinkingCoef + aCenterY); |
786 | aPnt.SetZ ((aPnt.Z() - aCenterZ) * theShrinkingCoef + aCenterZ); |
7fd59977 |
787 | } |
788 | |
37ac4a67 |
789 | aNodes.Append (aPnt); |
790 | } |
791 | |
792 | // Triangulate polygon |
793 | for (Standard_Integer aNodeIdx = 0; aNodeIdx < theNbNodes - 2; ++aNodeIdx) |
794 | { |
795 | for (Standard_Integer aSubIdx = 0; aSubIdx < 3; ++aSubIdx) |
7fd59977 |
796 | { |
37ac4a67 |
797 | if (theIsShaded) |
798 | { |
799 | if (theIsSmoothShading && aVertexNormals.Size() == theNbNodes) |
800 | { |
801 | aNormalX = aVertexNormals.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).X(); |
802 | aNormalY = aVertexNormals.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).Y(); |
803 | aNormalZ = aVertexNormals.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).Z(); |
804 | } |
805 | |
806 | theTriangles->AddVertex (aNodes.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).X(), |
807 | aNodes.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).Y(), |
808 | aNodes.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).Z(), |
809 | aNormalX, |
810 | aNormalY, |
811 | aNormalZ); |
812 | } |
813 | else |
814 | { |
815 | theTriangles->AddVertex (aNodes.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).X(), |
816 | aNodes.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).Y(), |
817 | aNodes.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).Z()); |
818 | } |
7fd59977 |
819 | } |
7fd59977 |
820 | } |
821 | } |
822 | |
823 | //================================================================ |
824 | // Function : AddVolumePrs |
825 | // Purpose : |
826 | //================================================================ |
37ac4a67 |
827 | void MeshVS_MeshPrsBuilder::AddVolumePrs (const Handle(MeshVS_HArray1OfSequenceOfInteger)& theTopo, |
828 | const TColStd_Array1OfReal& theNodes, |
829 | const Standard_Integer theNbNodes, |
830 | const Handle(Graphic3d_ArrayOfPrimitives)& theArray, |
831 | const Standard_Boolean theIsShaded, |
832 | const Standard_Boolean theIsShrinked, |
833 | const Standard_Boolean theIsSelected, |
834 | const Standard_Real theShrinkCoef) |
7fd59977 |
835 | { |
37ac4a67 |
836 | Standard_Real aCenter[] = { 0.0, 0.0, 0.0 }; |
7fd59977 |
837 | |
37ac4a67 |
838 | Standard_Integer aLow = theNodes.Lower(); |
839 | |
840 | if (theTopo.IsNull() || theArray.IsNull()) |
7fd59977 |
841 | return; |
842 | |
37ac4a67 |
843 | if (theIsShrinked) |
7fd59977 |
844 | { |
37ac4a67 |
845 | for (Standard_Integer aNodeIdx = 0; aNodeIdx < 3 * theNbNodes; ++aNodeIdx) |
846 | { |
847 | aCenter[aNodeIdx % 3] += theNodes.Value (aLow + aNodeIdx); |
848 | } |
7fd59977 |
849 | |
37ac4a67 |
850 | aCenter[0] /= theNbNodes; |
851 | aCenter[1] /= theNbNodes; |
852 | aCenter[2] /= theNbNodes; |
7fd59977 |
853 | } |
854 | |
37ac4a67 |
855 | Standard_Boolean aIsPolygons = theArray->IsKind (STANDARD_TYPE (Graphic3d_ArrayOfTriangles)); |
7fd59977 |
856 | |
37ac4a67 |
857 | if (aIsPolygons) |
858 | { |
859 | for (Standard_Integer aFaceIdx = theTopo->Lower(), topoup = theTopo->Upper(); aFaceIdx <= topoup; ++aFaceIdx) |
7fd59977 |
860 | { |
37ac4a67 |
861 | const TColStd_SequenceOfInteger& aFaceNodes = theTopo->Value (aFaceIdx); |
862 | const Standard_Integer aNbPolyNodes = aFaceNodes.Length(); |
7fd59977 |
863 | |
37ac4a67 |
864 | Standard_Real* aPolyNodesBuf = (Standard_Real*) alloca ((3 * aNbPolyNodes + 1) * sizeof (Standard_Real)); |
865 | TColStd_Array1OfReal aPolyNodes (*aPolyNodesBuf, 0, 3 * aNbPolyNodes); |
866 | |
867 | for (Standard_Integer aNodeIdx = 0; aNodeIdx < aNbPolyNodes; ++aNodeIdx) |
7fd59977 |
868 | { |
37ac4a67 |
869 | Standard_Integer anIdx = aFaceNodes.Value (aNodeIdx + 1); |
870 | |
871 | Standard_Real aX = theNodes.Value (aLow + 3 * anIdx + 0); |
872 | Standard_Real aY = theNodes.Value (aLow + 3 * anIdx + 1); |
873 | Standard_Real aZ = theNodes.Value (aLow + 3 * anIdx + 2); |
874 | |
875 | if (theIsShrinked) |
876 | { |
877 | aX = aCenter[0] + theShrinkCoef * (aX - aCenter[0]); |
878 | aY = aCenter[1] + theShrinkCoef * (aY - aCenter[1]); |
879 | aZ = aCenter[2] + theShrinkCoef * (aZ - aCenter[2]); |
7fd59977 |
880 | } |
881 | |
37ac4a67 |
882 | aPolyNodes.SetValue (3 * aNodeIdx + 1, aX); |
883 | aPolyNodes.SetValue (3 * aNodeIdx + 2, aY); |
884 | aPolyNodes.SetValue (3 * aNodeIdx + 3, aZ); |
7fd59977 |
885 | } |
37ac4a67 |
886 | |
887 | gp_Vec aNorm; |
7fd59977 |
888 | |
37ac4a67 |
889 | if (theIsShaded) |
7fd59977 |
890 | { |
37ac4a67 |
891 | aPolyNodes.SetValue (0, aNbPolyNodes); |
892 | |
893 | if (!MeshVS_Tool::GetAverageNormal (aPolyNodes, aNorm)) |
894 | { |
895 | aNorm.SetCoord (0.0, 0.0, 1.0); |
896 | } |
897 | } |
7fd59977 |
898 | |
37ac4a67 |
899 | for (Standard_Integer aNodeIdx = 0; aNodeIdx < aNbPolyNodes - 2; ++aNodeIdx) // triangulate polygon |
900 | { |
901 | for (Standard_Integer aSubIdx = 0; aSubIdx < 3; ++aSubIdx) // generate sub-triangle |
7fd59977 |
902 | { |
37ac4a67 |
903 | if (theIsShaded) |
904 | { |
905 | theArray->AddVertex (aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 1), |
906 | aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 2), |
907 | aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 3), |
908 | aNorm.X(), |
909 | aNorm.Y(), |
910 | aNorm.Z()); |
911 | } |
912 | else |
913 | { |
914 | theArray->AddVertex (aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 1), |
915 | aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 2), |
916 | aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 3)); |
917 | } |
7fd59977 |
918 | } |
7fd59977 |
919 | } |
920 | } |
921 | } |
37ac4a67 |
922 | else if (theIsSelected) |
7fd59977 |
923 | { |
37ac4a67 |
924 | for (Standard_Integer aFaceIdx = theTopo->Lower(), topoup = theTopo->Upper(); aFaceIdx <= topoup; ++aFaceIdx) |
7fd59977 |
925 | { |
37ac4a67 |
926 | const TColStd_SequenceOfInteger& aFaceNodes = theTopo->Value (aFaceIdx); |
927 | |
928 | Standard_Real aFaceCenter[] = { 0.0, 0.0, 0.0 }; |
929 | |
930 | for (Standard_Integer aNodeIdx = 1; aNodeIdx <= aFaceNodes.Length(); ++aNodeIdx) |
7fd59977 |
931 | { |
37ac4a67 |
932 | for (Standard_Integer aAxisIdx = 0; aAxisIdx < 3; ++aAxisIdx) |
933 | { |
934 | aFaceCenter[aAxisIdx] += theNodes.Value (aLow + 3 * aFaceNodes.Value (aNodeIdx) + aAxisIdx); |
935 | } |
7fd59977 |
936 | } |
7fd59977 |
937 | |
37ac4a67 |
938 | aFaceCenter[0] /= aFaceNodes.Length(); |
939 | aFaceCenter[1] /= aFaceNodes.Length(); |
940 | aFaceCenter[2] /= aFaceNodes.Length(); |
941 | |
942 | for (Standard_Integer aNodeIdx = 0, aNbNodes = aFaceNodes.Length(); aNodeIdx < aNbNodes; ++aNodeIdx) |
7fd59977 |
943 | { |
37ac4a67 |
944 | for (Standard_Integer aSubIdx = 0; aSubIdx < 2; ++aSubIdx) // add segment |
945 | { |
946 | Standard_Integer anIdx = aFaceNodes.Value ((aNodeIdx + aSubIdx) % aNbNodes + 1); |
947 | |
948 | Standard_Real aX = theNodes.Value (aLow + 3 * anIdx + 0); |
949 | Standard_Real aY = theNodes.Value (aLow + 3 * anIdx + 1); |
950 | Standard_Real aZ = theNodes.Value (aLow + 3 * anIdx + 2); |
951 | |
952 | theArray->AddVertex (aFaceCenter[0] + theShrinkCoef * (aX - aFaceCenter[0]), |
953 | aFaceCenter[1] + theShrinkCoef * (aY - aFaceCenter[1]), |
954 | aFaceCenter[2] + theShrinkCoef * (aZ - aFaceCenter[2])); |
955 | } |
7fd59977 |
956 | } |
957 | } |
958 | } |
959 | else |
960 | { |
37ac4a67 |
961 | // Find all pairs of nodes (edges) to draw (will be drawn only once) |
962 | NCollection_Map<MeshVS_NodePair, MeshVS_SymmetricPairHasher> aEdgeMap; |
7fd59977 |
963 | |
37ac4a67 |
964 | for (Standard_Integer aFaceIdx = theTopo->Lower(), topoup = theTopo->Upper(); aFaceIdx <= topoup; ++aFaceIdx) |
7fd59977 |
965 | { |
37ac4a67 |
966 | const TColStd_SequenceOfInteger& aFaceNodes = theTopo->Value (aFaceIdx); |
967 | |
968 | for (Standard_Integer aNodeIdx = 0, aNbNodes = aFaceNodes.Length(); aNodeIdx < aNbNodes; ++aNodeIdx) |
7fd59977 |
969 | { |
37ac4a67 |
970 | const Standard_Integer aNextIdx = (aNodeIdx + 1) % aNbNodes; |
7fd59977 |
971 | |
37ac4a67 |
972 | aEdgeMap.Add (MeshVS_NodePair (aFaceNodes.Value (aNodeIdx + 1), |
973 | aFaceNodes.Value (aNextIdx + 1))); |
7fd59977 |
974 | } |
975 | } |
976 | |
37ac4a67 |
977 | // Draw edges |
978 | for(NCollection_Map<MeshVS_NodePair, MeshVS_SymmetricPairHasher>::Iterator anIt (aEdgeMap); anIt.More(); anIt.Next()) |
7fd59977 |
979 | { |
37ac4a67 |
980 | const Standard_Integer anIdx1 = aLow + 3 * anIt.Key().first; |
981 | const Standard_Integer anIdx2 = aLow + 3 * anIt.Key().second; |
982 | |
983 | Standard_Real aX[] = { theNodes.Value (anIdx1 + 0), theNodes.Value (anIdx2 + 0) }; |
984 | Standard_Real aY[] = { theNodes.Value (anIdx1 + 1), theNodes.Value (anIdx2 + 1) }; |
985 | Standard_Real aZ[] = { theNodes.Value (anIdx1 + 2), theNodes.Value (anIdx2 + 2) }; |
986 | |
987 | if (theIsShrinked) |
988 | { |
989 | for (Standard_Integer anAxisIdx = 0; anAxisIdx < 2; ++anAxisIdx) |
7fd59977 |
990 | { |
37ac4a67 |
991 | aX[anAxisIdx] = aCenter[0] + theShrinkCoef * (aX[anAxisIdx] - aCenter[0]); |
992 | aY[anAxisIdx] = aCenter[1] + theShrinkCoef * (aY[anAxisIdx] - aCenter[1]); |
993 | aZ[anAxisIdx] = aCenter[2] + theShrinkCoef * (aZ[anAxisIdx] - aCenter[2]); |
7fd59977 |
994 | } |
37ac4a67 |
995 | } |
7fd59977 |
996 | |
37ac4a67 |
997 | theArray->AddVertex (aX[0], aY[0], aZ[0]); |
998 | theArray->AddVertex (aX[1], aY[1], aZ[1]); |
7fd59977 |
999 | } |
1000 | } |
1001 | } |
1002 | |
1003 | //================================================================ |
1004 | // Function : HowManyPrimitives |
1005 | // Purpose : |
1006 | //================================================================ |
1007 | void MeshVS_MeshPrsBuilder::HowManyPrimitives (const Handle(MeshVS_HArray1OfSequenceOfInteger)& Topo, |
1008 | const Standard_Boolean AsPolygons, |
1009 | const Standard_Boolean IsSelect, |
1010 | const Standard_Integer NbNodes, |
1011 | Standard_Integer& Vertices, |
1012 | Standard_Integer& Bounds) |
1013 | { |
eafb234b |
1014 | if( !Topo.IsNull() ) { |
7fd59977 |
1015 | if( AsPolygons || IsSelect ) |
1016 | { |
1017 | Standard_Integer B = Topo->Upper()-Topo->Lower()+1; |
1018 | Bounds += B; |
1019 | for( Standard_Integer i=Topo->Lower(), n=Topo->Upper(); i<=n; i++ ) |
1020 | Vertices += Topo->Value( i ).Length(); |
1021 | |
1022 | if( IsSelect ) |
1023 | Vertices+=B; |
1024 | } |
1025 | else |
1026 | { |
1027 | Standard_Integer F = Topo->Upper()-Topo->Lower()+1, |
1028 | E = NbNodes + F - 2; |
1029 | // number of edges is obtained by Euler's expression for polyhedrons |
1030 | |
1031 | Bounds += E; |
1032 | Vertices += 2*E; |
1033 | } |
eafb234b |
1034 | } |
7fd59977 |
1035 | } |
1036 | |
1037 | //================================================================ |
1038 | // Function : DrawArrays |
1039 | // Purpose : |
1040 | //================================================================ |
1041 | void MeshVS_MeshPrsBuilder::DrawArrays( const Handle(Prs3d_Presentation)& Prs, |
37ac4a67 |
1042 | const Handle(Graphic3d_ArrayOfPrimitives)& thePolygons, |
1043 | const Handle(Graphic3d_ArrayOfPrimitives)& theLines, |
1044 | const Handle(Graphic3d_ArrayOfPrimitives)& theLinkLines, |
1045 | const Handle(Graphic3d_ArrayOfPrimitives)& theVolumesInShad, |
7fd59977 |
1046 | const Standard_Boolean IsPolygonsEdgesOff, |
1047 | const Standard_Boolean IsSelected, |
1048 | const Handle(Graphic3d_AspectFillArea3d)& theFillAsp, |
1049 | const Handle(Graphic3d_AspectLine3d)& theLineAsp ) const |
1050 | { |
1051 | if ( theFillAsp.IsNull() ) |
1052 | return; |
1053 | |
1054 | Standard_Boolean IsFacePolygons = ( !thePolygons.IsNull() && thePolygons->ItemNumber() > 0 ), |
1055 | IsVolumePolygons = ( !theVolumesInShad.IsNull() && theVolumesInShad->ItemNumber() > 0 ), |
1056 | IsPolygons = IsFacePolygons || IsVolumePolygons, |
1057 | IsPolylines = ( !theLines.IsNull() && theLines->ItemNumber() > 0 ), |
1058 | IsLinkPolylines = ( !theLinkLines.IsNull() && theLinkLines->ItemNumber() > 0 ); |
1059 | |
1060 | Aspect_InteriorStyle aStyle; |
1061 | Quantity_Color anIntColor, aBackColor, anEdgeColor; |
1062 | Aspect_TypeOfLine aType; |
1063 | Standard_Real aWidth; |
1064 | |
1065 | theFillAsp->Values( aStyle, anIntColor, aBackColor, anEdgeColor, aType, aWidth ); |
1066 | |
c3715b74 |
1067 | Standard_Boolean isSupressBackFaces = Standard_False; |
1068 | Handle(MeshVS_Drawer) aDrawer = GetDrawer(); |
1069 | if (!aDrawer.IsNull()) |
1070 | { |
1071 | aDrawer->GetBoolean (MeshVS_DA_SupressBackFaces, isSupressBackFaces); |
1072 | } |
1073 | |
7fd59977 |
1074 | if ( IsPolygons && theFillAsp->FrontMaterial().Transparency()<0.01 ) |
1075 | { |
1076 | Prs3d_Root::NewGroup ( Prs ); |
1077 | Handle (Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup ( Prs ); |
1078 | |
1079 | //if ( IsPolygonsEdgesOff ) |
1080 | theFillAsp->SetEdgeOff (); |
1081 | //else |
1082 | // theFillAsp->SetEdgeOn (); |
1083 | |
1084 | if( anIntColor!=aBackColor ) |
1085 | theFillAsp->SetDistinguishOn(); |
1086 | else |
1087 | theFillAsp->SetDistinguishOff(); |
1088 | |
c3715b74 |
1089 | aGroup->SetClosed (isSupressBackFaces); |
1090 | Handle(Graphic3d_AspectFillArea3d) aFillAsp = new Graphic3d_AspectFillArea3d (*(theFillAsp.operator->())); |
1091 | if (isSupressBackFaces) |
1092 | { |
1093 | aFillAsp->SuppressBackFace(); |
1094 | } |
1095 | aGroup->SetPrimitivesAspect (aFillAsp); |
1096 | |
7fd59977 |
1097 | if( IsFacePolygons ) |
1098 | { |
7fd59977 |
1099 | aGroup->AddPrimitiveArray ( thePolygons ); |
7fd59977 |
1100 | } |
1101 | |
1102 | if( IsVolumePolygons ) |
1103 | { |
7fd59977 |
1104 | aGroup->AddPrimitiveArray ( theVolumesInShad ); |
7fd59977 |
1105 | } |
1106 | } |
1107 | |
1108 | if ( IsPolylines && !IsPolygonsEdgesOff ) |
1109 | { |
1110 | Prs3d_Root::NewGroup ( Prs ); |
1111 | Handle (Graphic3d_Group) aLGroup = Prs3d_Root::CurrentGroup ( Prs ); |
1112 | |
1113 | theFillAsp->SetEdgeOff(); |
1114 | if ( IsSelected ) |
1115 | aLGroup->SetPrimitivesAspect ( theLineAsp ); |
1116 | else |
1117 | { |
1118 | aLGroup->SetPrimitivesAspect ( theFillAsp ); |
1119 | aLGroup->SetPrimitivesAspect ( new Graphic3d_AspectLine3d |
1120 | ( anEdgeColor, Aspect_TOL_SOLID, aWidth ) ); |
1121 | } |
7fd59977 |
1122 | aLGroup->AddPrimitiveArray ( theLines ); |
7fd59977 |
1123 | theFillAsp->SetEdgeOn(); |
1124 | } |
1125 | |
1126 | if ( IsLinkPolylines ) |
1127 | { |
1128 | Prs3d_Root::NewGroup ( Prs ); |
1129 | Handle (Graphic3d_Group) aBeamGroup = Prs3d_Root::CurrentGroup ( Prs ); |
1130 | |
1131 | theFillAsp->SetEdgeOff(); |
1132 | if ( !IsSelected ) |
1133 | aBeamGroup->SetPrimitivesAspect ( theFillAsp ); |
1134 | aBeamGroup->SetPrimitivesAspect ( theLineAsp ); |
7fd59977 |
1135 | aBeamGroup->AddPrimitiveArray ( theLinkLines ); |
7fd59977 |
1136 | theFillAsp->SetEdgeOn(); |
1137 | } |
1138 | |
1139 | if ( IsPolygons && theFillAsp->FrontMaterial().Transparency()>=0.01 ) |
1140 | { |
1141 | Prs3d_Root::NewGroup ( Prs ); |
1142 | Handle (Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup ( Prs ); |
1143 | |
1144 | //if ( IsPolygonsEdgesOff ) |
1145 | theFillAsp->SetEdgeOff (); |
1146 | //else |
1147 | // theFillAsp->SetEdgeOn (); |
1148 | |
1149 | if( anIntColor!=aBackColor ) |
1150 | theFillAsp->SetDistinguishOn(); |
1151 | else |
1152 | theFillAsp->SetDistinguishOff(); |
1153 | |
c3715b74 |
1154 | aGroup->SetClosed (isSupressBackFaces); |
1155 | Handle(Graphic3d_AspectFillArea3d) aFillAsp = new Graphic3d_AspectFillArea3d (*(theFillAsp.operator->())); |
1156 | if (isSupressBackFaces) |
1157 | { |
1158 | aFillAsp->SuppressBackFace(); |
1159 | } |
1160 | aGroup->SetPrimitivesAspect (aFillAsp); |
1161 | |
7fd59977 |
1162 | if( IsFacePolygons ) |
1163 | { |
7fd59977 |
1164 | aGroup->AddPrimitiveArray ( thePolygons ); |
7fd59977 |
1165 | } |
1166 | |
1167 | if( IsVolumePolygons ) |
1168 | { |
7fd59977 |
1169 | aGroup->AddPrimitiveArray ( theVolumesInShad ); |
7fd59977 |
1170 | } |
1171 | } |
1172 | } |
1173 | |
1174 | //================================================================ |
1175 | // Function : CalculateCenter |
1176 | // Purpose : |
1177 | //================================================================ |
1178 | void MeshVS_MeshPrsBuilder::CalculateCenter (const TColStd_Array1OfReal& theCoords, |
1179 | const Standard_Integer NbNodes, |
1180 | Standard_Real &xG, |
1181 | Standard_Real &yG, |
1182 | Standard_Real &zG) |
1183 | { |
1184 | xG = yG = zG = 0; |
1185 | if ( NbNodes < 4 ) |
1186 | { |
1187 | for ( Standard_Integer k=1; k<=NbNodes; k++) |
1188 | { |
1189 | xG += theCoords(3*k-2); |
1190 | yG += theCoords(3*k-1); |
1191 | zG += theCoords(3*k); |
1192 | } |
1193 | xG /= Standard_Real(NbNodes); |
1194 | yG /= Standard_Real(NbNodes); |
1195 | zG /= Standard_Real(NbNodes); |
1196 | } |
1197 | else |
1198 | { |
1199 | Standard_Integer a = 1, b = 3; |
1200 | xG = ( theCoords( 3*a-2 ) + theCoords( 3*b-2 ) ) / 2.0; |
1201 | yG = ( theCoords( 3*a-1 ) + theCoords( 3*b-1 ) ) / 2.0; |
1202 | zG = ( theCoords( 3*a ) + theCoords( 3*b ) ) / 2.0; |
1203 | } |
1204 | } |