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