1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-14 13:30:48 +03:00

0024926: MeshVS - improve generation of primitive arrays

Remove redundant code.

Fix GCC compilation warnings.

Bug fix in MeshVS_ElementalColorPrsBuilder.
This commit is contained in:
dbp
2014-07-24 13:21:54 +04:00
committed by bugmaster
parent 14434f3e6c
commit 37ac4a67fc
8 changed files with 1156 additions and 704 deletions

View File

@@ -7,3 +7,4 @@ MeshVS_TwoColors.hxx
MeshVS_TwoColors.cxx
MeshVS_TwoNodes.hxx
MeshVS_SelectionModeFlags.hxx
MeshVS_SymmetricPairHasher.hxx

View File

@@ -19,6 +19,8 @@
#include <Graphic3d_AspectLine3d.hxx>
#include <Graphic3d_ArrayOfPolygons.hxx>
#include <Graphic3d_ArrayOfPolylines.hxx>
#include <Graphic3d_ArrayOfSegments.hxx>
#include <Graphic3d_ArrayOfTriangles.hxx>
#include <Graphic3d_Group.hxx>
#include <Prs3d_ShadingAspect.hxx>
@@ -47,7 +49,7 @@
#include <MeshVS_DataMapIteratorOfDataMapOfColorMapOfInteger.hxx>
#include <MeshVS_MeshPrsBuilder.hxx>
#include <MeshVS_Buffer.hxx>
#include <MeshVS_HArray1OfSequenceOfInteger.hxx>
//================================================================
// Function : Constructor MeshVS_ElementalColorPrsBuilder
@@ -210,8 +212,7 @@ void MeshVS_ElementalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)&
}
Graphic3d_MaterialAspect aMaterial[2];
Standard_Integer i;
for ( i=0; i<2; i++ )
for (Standard_Integer i = 0; i < 2; i++)
{
// OCC20644 "plastic" is most suitable here, as it is "non-physic"
// so TelUpdateMaterial() from OpenGl_attri.c uses the interior
@@ -257,121 +258,219 @@ void MeshVS_ElementalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)&
Handle ( Graphic3d_Group ) aGGroup = Prs3d_Root::CurrentGroup ( Prs );
Prs3d_Root::NewGroup ( Prs );
Handle ( Graphic3d_Group ) aLGroup = Prs3d_Root::CurrentGroup ( Prs );
Prs3d_Root::NewGroup ( Prs );
Handle ( Graphic3d_Group ) aSGroup = Prs3d_Root::CurrentGroup ( Prs );
Handle (Graphic3d_ArrayOfPolygons) aPolyGArr = new Graphic3d_ArrayOfPolygons
( aMaxFaceNodes*aSize + PolygonVerticesFor3D, aSize + PolygonBoundsFor3D, 0, IsReflect );
Standard_Integer aNbFacePrimitives = 0;
Standard_Integer aNbVolmPrimitives = 0;
Standard_Integer aNbEdgePrimitives = 0;
Standard_Integer aNbLinkPrimitives = 0;
for (it.Reset(); it.More(); it.Next())
{
Standard_Integer aNbNodes = 0;
if (!aColIter.Value().Contains (it.Key()))
continue;
if (!aSource->GetGeom (it.Key(), Standard_True, aCoords, aNbNodes, aType))
continue;
if (aType == MeshVS_ET_Volume)
{
if (aSource->Get3DGeom (it.Key(), aNbNodes, aTopo))
{
for (Standard_Integer aFaceIdx = aTopo->Lower(); aFaceIdx <= aTopo->Upper(); ++aFaceIdx)
{
const TColStd_SequenceOfInteger& aFaceNodes = aTopo->Value (aFaceIdx);
if (anEdgeOn) // add edge segments
{
aNbEdgePrimitives += aFaceNodes.Length();
}
if (IsReflect) // add volumetric cell triangles
{
aNbVolmPrimitives += aFaceNodes.Length() - 2;
}
}
}
}
else if (aType == MeshVS_ET_Link)
{
if (anEdgeOn)
{
aNbLinkPrimitives += aNbNodes - 1; // add link segments
}
}
else if (aType == MeshVS_ET_Face)
{
if (anEdgeOn)
{
aNbEdgePrimitives += aNbNodes; // add edge segments
}
aNbFacePrimitives += aNbNodes - 2; // add face triangles
}
}
// Here we do not use indices arrays because they are not effective for some mesh
// drawing modes: shrinking mode (displaces the vertices inside the polygon), 3D
// cell rendering (normal interpolation is not always applicable - flat shading),
// elemental coloring (color interpolation is impossible)
Handle (Graphic3d_ArrayOfTriangles) aFaceTriangles = new Graphic3d_ArrayOfTriangles (
(aNbFacePrimitives + aNbVolmPrimitives) * 3, 0, IsReflect );
Standard_Boolean IsPolyG = Standard_False;
Handle (Graphic3d_ArrayOfPolylines) aPolyLArr = new Graphic3d_ArrayOfPolylines
( 2*aSize, aSize );
Handle (Graphic3d_ArrayOfSegments) anEdgeSegments = new Graphic3d_ArrayOfSegments (aNbEdgePrimitives * 2);
Handle (Graphic3d_ArrayOfSegments) aLinkSegments = new Graphic3d_ArrayOfSegments (aNbLinkPrimitives * 2);
Standard_Boolean IsPolyL = Standard_False;
// OCC20644 NOTE: aColIter.Key() color is then scaled by TelUpdateMaterial() in OpenGl_attri.c
// using the material reflection coefficients. This affects the visual result.
Handle(Graphic3d_AspectFillArea3d) anAsp =
Handle(Graphic3d_AspectFillArea3d) aFillAspect =
new Graphic3d_AspectFillArea3d ( Aspect_IS_SOLID, aColIter.Key(), anEdgeColor,
anEdgeType, anEdgeWidth, aMaterial[0], aMaterial[1] );
Handle(Graphic3d_AspectLine3d) anLAsp =
Handle(Graphic3d_AspectLine3d) aLinkAspect =
new Graphic3d_AspectLine3d ( aColIter.Key(), aLineType, aLineWidth );
anAsp->SetDistinguishOff ();
anAsp->SetInteriorColor ( aColIter.Key() );
Handle(Graphic3d_AspectLine3d) anEdgeAspect =
new Graphic3d_AspectLine3d ( anEdgeColor, anEdgeType, anEdgeWidth );
aFillAspect->SetDistinguishOff ();
aFillAspect->SetInteriorColor ( aColIter.Key() );
if (anEdgeOn)
anAsp->SetEdgeOn();
aFillAspect->SetEdgeOn();
else
anAsp->SetEdgeOff();
aFillAspect->SetEdgeOff();
for (it.Reset(); it.More(); it.Next())
{
Standard_Integer aKey = it.Key();
if (aColIter.Value().Contains (aKey))
{
if (!aSource->GetGeom (aKey, Standard_True, aCoords, NbNodes, aType))
continue;
if( aType == MeshVS_ET_Face )
{
aPolyGArr->AddBound ( NbNodes );
if( IsExcludingOn() )
IDsToExclude.Add( aKey );
}
else if( aType == MeshVS_ET_Link )
{
aPolyLArr->AddBound ( NbNodes );
if( IsExcludingOn() )
IDsToExclude.Add( aKey );
}
else if( aType == MeshVS_ET_Volume )
{
if( IsExcludingOn() )
IDsToExclude.Add( aKey );
if( aSource->Get3DGeom( aKey, NbNodes, aTopo ) )
{
MeshVS_MeshPrsBuilder::AddVolumePrs( aTopo, aCoords, NbNodes, aPolyGArr, IsReflect, Standard_False, Standard_False, 1.0 );
IsPolyG = Standard_True;
}
else
continue;
}
else
if (aType != MeshVS_ET_Face && aType != MeshVS_ET_Link && aType != MeshVS_ET_Volume)
{
aCustomElements.Add (aKey);
continue;
}
// Preparing normal(s) to show reflections if requested
Handle(TColStd_HArray1OfReal) aNormals;
Standard_Boolean hasNormals = IsReflect && aSource->GetNormalsByElement( aKey, IsMeshSmoothShading, aMaxFaceNodes, aNormals );
if (IsExcludingOn())
IDsToExclude.Add (aKey);
// Adding vertices (with normals if necessary)
for ( i=1; i<=NbNodes; i++ )
if ( aType == MeshVS_ET_Face )
if (aType == MeshVS_ET_Volume)
{
if (!aSource->Get3DGeom (aKey, NbNodes, aTopo))
{
continue;
}
MeshVS_MeshPrsBuilder::AddVolumePrs (aTopo, aCoords,
NbNodes, aFaceTriangles, IsReflect, Standard_False, Standard_False, 1.0);
if (anEdgeOn)
{
MeshVS_MeshPrsBuilder::AddVolumePrs (aTopo, aCoords,
NbNodes, anEdgeSegments, IsReflect, Standard_False, Standard_False, 1.0);
}
IsPolyG = Standard_True;
}
else if (aType == MeshVS_ET_Face)
{
// Preparing normals
Handle(TColStd_HArray1OfReal) aNormals;
Standard_Boolean aHasNormals = IsReflect && aSource->GetNormalsByElement (aKey, IsMeshSmoothShading, aMaxFaceNodes, aNormals);
for (Standard_Integer aNodeIdx = 0; aNodeIdx < NbNodes - 2; ++aNodeIdx)
{
for (Standard_Integer anIdx = 0; anIdx < 3; ++anIdx)
{
if (IsReflect)
{
hasNormals ? aPolyGArr->AddVertex ( aCoords(3 * i - 2),
aCoords(3 * i - 1),
aCoords(3 * i ),
aNormals->Value(3 * i - 2),
aNormals->Value(3 * i - 1),
aNormals->Value(3 * i ) ) :
aPolyGArr->AddVertex ( aCoords(3 * i - 2),
aCoords(3 * i - 1),
aCoords(3 * i ),
0.,
0.,
1. );
aFaceTriangles->AddVertex (aCoords (3 * (anIdx == 0 ? 0 : (aNodeIdx + anIdx)) + 1),
aCoords (3 * (anIdx == 0 ? 0 : (aNodeIdx + anIdx)) + 2),
aCoords (3 * (anIdx == 0 ? 0 : (aNodeIdx + anIdx)) + 3),
aHasNormals ? aNormals->Value (3 * (anIdx == 0 ? 0 : (aNodeIdx + anIdx)) + 1) : 0.0,
aHasNormals ? aNormals->Value (3 * (anIdx == 0 ? 0 : (aNodeIdx + anIdx)) + 2) : 0.0,
aHasNormals ? aNormals->Value (3 * (anIdx == 0 ? 0 : (aNodeIdx + anIdx)) + 3) : 1.0);
}
else
aPolyGArr->AddVertex ( aCoords(3 * i - 2),
aCoords(3 * i - 1),
aCoords(3 * i ) );
{
aFaceTriangles->AddVertex (aCoords (3 * (anIdx == 0 ? 0 : (aNodeIdx + anIdx)) + 1),
aCoords (3 * (anIdx == 0 ? 0 : (aNodeIdx + anIdx)) + 2),
aCoords (3 * (anIdx == 0 ? 0 : (aNodeIdx + anIdx)) + 3));
}
}
}
if (anEdgeOn)
{
for (Standard_Integer aNodeIdx = 0; aNodeIdx < NbNodes; ++aNodeIdx)
{
const Standard_Integer aNextIdx = (aNodeIdx + 1) % NbNodes;
anEdgeSegments->AddVertex (aCoords (3 * aNodeIdx + 1),
aCoords (3 * aNodeIdx + 2),
aCoords (3 * aNodeIdx + 3));
anEdgeSegments->AddVertex (aCoords (3 * aNextIdx + 1),
aCoords (3 * aNextIdx + 2),
aCoords (3 * aNextIdx + 3));
}
}
IsPolyG = Standard_True;
}
else if (aType == MeshVS_ET_Link)
{
aPolyLArr->AddVertex ( aCoords(3*i-2), aCoords(3*i-1), aCoords(3*i) );
for (Standard_Integer aNodeIdx = 0; aNodeIdx < NbNodes - 1; ++aNodeIdx)
{
const Standard_Integer aNextIdx = aNodeIdx + 1;
aLinkSegments->AddVertex (aCoords (3 * aNodeIdx + 1),
aCoords (3 * aNodeIdx + 2),
aCoords (3 * aNodeIdx + 3));
aLinkSegments->AddVertex (aCoords (3 * aNextIdx + 1),
aCoords (3 * aNextIdx + 2),
aCoords (3 * aNextIdx + 3));
IsPolyL = Standard_True;
}
}
}
}
if (IsPolyG)
{
aGGroup->SetPrimitivesAspect ( anAsp );
aGGroup->AddPrimitiveArray ( aPolyGArr );
aFillAspect->SetEdgeOff();
aGGroup->SetPrimitivesAspect (aFillAspect);
aGGroup->AddPrimitiveArray (aFaceTriangles);
if (anEdgeOn)
{
aFillAspect->SetEdgeOff();
aSGroup->AddPrimitiveArray (anEdgeSegments);
aSGroup->SetGroupPrimitivesAspect (anEdgeAspect);
}
}
if (IsPolyL)
{
anAsp->SetEdgeOff();
aLGroup->SetPrimitivesAspect ( anAsp );
aLGroup->SetPrimitivesAspect ( anLAsp );
aLGroup->AddPrimitiveArray ( aPolyLArr );
aFillAspect->SetEdgeOff();
aLGroup->SetPrimitivesAspect (aFillAspect);
aLGroup->SetPrimitivesAspect (aLinkAspect);
aLGroup->AddPrimitiveArray (aLinkSegments);
if (anEdgeOn)
anAsp->SetEdgeOn();
aFillAspect->SetEdgeOn();
else
anAsp->SetEdgeOff();
aFillAspect->SetEdgeOff();
}
if (!aCustomElements.IsEmpty())
@@ -379,7 +478,7 @@ void MeshVS_ElementalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)&
}
Graphic3d_MaterialAspect aMaterial2[2];
for ( i=0; i<2; i++ )
for (Standard_Integer i = 0; i < 2; i++)
{
// OCC20644 "plastic" is most suitable here, as it is "non-physic"
// so TelUpdateMaterial() from OpenGl_attri.c uses the interior
@@ -422,13 +521,42 @@ void MeshVS_ElementalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)&
{
Prs3d_Root::NewGroup ( Prs );
Handle ( Graphic3d_Group ) aGroup2 = Prs3d_Root::CurrentGroup ( Prs );
Prs3d_Root::NewGroup ( Prs );
Handle ( Graphic3d_Group ) aGroup3 = Prs3d_Root::CurrentGroup ( Prs );
Standard_Integer aSize = aColIter2.Value().Extent();
if ( aSize<=0 )
continue;
Handle (Graphic3d_ArrayOfPolygons) aPolyArr = new Graphic3d_ArrayOfPolygons
( aMaxFaceNodes*aSize, aSize, 0, IsReflect );
Standard_Integer aNbFacePrimitives = 0;
Standard_Integer aNbEdgePrimitives = 0;
for (it.Reset(); it.More(); it.Next())
{
Standard_Integer aNbNodes = 0;
if (!aColIter2.Value().Contains (it.Key()))
continue;
if (!aSource->GetGeom (it.Key(), Standard_True, aCoords, aNbNodes, aType))
continue;
if ( aType == MeshVS_ET_Face && aNbNodes > 0 )
{
if (anEdgeOn)
{
aNbEdgePrimitives += aNbNodes; // add edge segments
}
aNbFacePrimitives += aNbNodes - 2; // add face triangles
}
}
Handle (Graphic3d_ArrayOfTriangles) aFaceTriangles = new Graphic3d_ArrayOfTriangles
(aNbFacePrimitives * 3, 0, IsReflect);
Handle (Graphic3d_ArrayOfSegments) anEdgeSegments = new Graphic3d_ArrayOfSegments
(aNbEdgePrimitives * 2);
MeshVS_TwoColors aTC = aColIter2.Key();
Quantity_Color aMyIntColor, aMyBackColor;
@@ -442,12 +570,13 @@ void MeshVS_ElementalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)&
anAsp->SetDistinguishOn ();
anAsp->SetInteriorColor ( aMyIntColor );
anAsp->SetBackInteriorColor ( aMyBackColor );
if (anEdgeOn)
/*if (anEdgeOn)
anAsp->SetEdgeOn();
else
anAsp->SetEdgeOff();
anAsp->SetEdgeOff();*/
aGroup2->SetPrimitivesAspect ( anAsp );
Handle(Graphic3d_AspectLine3d) anEdgeAspect =
new Graphic3d_AspectLine3d (anEdgeColor, anEdgeType, anEdgeWidth);
for( it.Reset(); it.More(); it.Next() )
{
@@ -466,37 +595,54 @@ void MeshVS_ElementalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)&
Handle(TColStd_HArray1OfReal) aNormals;
// OCC21720 Always passing normals to OpenGL to make materials work
// For OpenGL: "No normals" -> "No lighting" -> "no materials taken into account"
Standard_Boolean hasNormals = /*IsReflect &&*/
Standard_Boolean aHasNormals = /*IsReflect &&*/
aSource->GetNormalsByElement (aKey, IsMeshSmoothShading, aMaxFaceNodes, aNormals);
aPolyArr->AddBound ( NbNodes );
for ( i=1; i<=NbNodes; i++ )
for (Standard_Integer aNodeIdx = 0; aNodeIdx < NbNodes - 2; ++aNodeIdx)
{
for (Standard_Integer anIdx = 0; anIdx < 3; ++anIdx)
{
if (IsReflect)
{
hasNormals ? aPolyArr->AddVertex ( aCoords(3 * i - 2),
aCoords(3 * i - 1),
aCoords(3 * i ),
aNormals->Value(3 * i - 2),
aNormals->Value(3 * i - 1),
aNormals->Value(3 * i ) ) :
aPolyArr->AddVertex ( aCoords(3 * i - 2),
aCoords(3 * i - 1),
aCoords(3 * i ),
0.,
0.,
1. );
aFaceTriangles->AddVertex (aCoords (3 * (anIdx == 0 ? 0 : aNodeIdx + anIdx) + 1),
aCoords (3 * (anIdx == 0 ? 0 : aNodeIdx + anIdx) + 2),
aCoords (3 * (anIdx == 0 ? 0 : aNodeIdx + anIdx) + 3),
aHasNormals ? aNormals->Value (3 * (anIdx == 0 ? 0 : aNodeIdx + anIdx) + 1) : 0.0,
aHasNormals ? aNormals->Value (3 * (anIdx == 0 ? 0 : aNodeIdx + anIdx) + 2) : 0.0,
aHasNormals ? aNormals->Value (3 * (anIdx == 0 ? 0 : aNodeIdx + anIdx) + 3) : 1.0);
}
else
aPolyArr->AddVertex ( aCoords(3*i-2),
aCoords(3*i-1),
aCoords(3*i ) );
{
aFaceTriangles->AddVertex (aCoords (3 * (anIdx == 0 ? 0 : aNodeIdx + anIdx) + 1),
aCoords (3 * (anIdx == 0 ? 0 : aNodeIdx + anIdx) + 2),
aCoords (3 * (anIdx == 0 ? 0 : aNodeIdx + anIdx) + 3));
}
}
}
if (anEdgeOn)
{
for (Standard_Integer aNodeIdx = 0; aNodeIdx < NbNodes; ++aNodeIdx)
{
const Standard_Integer aNextIdx = (aNodeIdx + 1) % NbNodes;
anEdgeSegments->AddVertex (aCoords (3 * aNodeIdx + 1),
aCoords (3 * aNodeIdx + 2),
aCoords (3 * aNodeIdx + 3));
anEdgeSegments->AddVertex (aCoords (3 * aNextIdx + 1),
aCoords (3 * aNextIdx + 2),
aCoords (3 * aNextIdx + 3));
}
}
}
}
aGroup2->AddPrimitiveArray ( aPolyArr );
}
aGroup2->AddPrimitiveArray (aFaceTriangles);
aGroup2->SetGroupPrimitivesAspect (anAsp);
aGroup3->AddPrimitiveArray (anEdgeSegments);
aGroup3->SetGroupPrimitivesAspect (anEdgeAspect);
}
}

View File

@@ -37,8 +37,10 @@ uses
AspectMarker3d from Graphic3d,
Array1OfReal from TColStd,
ArrayOfPolylines from Graphic3d,
ArrayOfSegments from Graphic3d,
ArrayOfPolygons from Graphic3d,
ArrayOfPrimitives from Graphic3d,
ArrayOfTriangles from Graphic3d,
PackedMapOfInteger from TColStd
is
@@ -76,29 +78,30 @@ is
---Purpose: Builds presentation of hilighted entity
AddLinkPrs ( me; theCoords : Array1OfReal from TColStd;
theLines : ArrayOfPolylines from Graphic3d;
theLines : ArrayOfSegments from Graphic3d;
IsShrinked : Boolean;
ShrinkCoef : Real
) is protected;
---Purpose: Add to array of polylines some lines representing link
AddFaceWirePrs ( me; theCoords : Array1OfReal from TColStd;
NbNodes : Integer;
theLines : ArrayOfPolylines from Graphic3d;
IsShrinked : Boolean;
ShrinkCoef : Real
AddFaceWirePrs ( me;
theCoords : Array1OfReal from TColStd;
theNbNodes : Integer;
theLines : ArrayOfSegments from Graphic3d;
theIsShrinked : Boolean;
theShrinkingCoef : Real
) is protected;
---Purpose: Add to array of polylines some lines representing face's wire
---Purpose: Add to array of segments representing face's wire
AddFaceSolidPrs ( me; ID : Integer;
theCoords : Array1OfReal from TColStd;
NbNodes : Integer;
MaxNodes : Integer;
thePolygons : ArrayOfPolygons from Graphic3d;
IsReflected : Boolean;
IsShrinked : Boolean;
ShrinkCoef : Real;
IsMeshSmoothShading : Boolean
theNbNodes : Integer;
theMaxNodes : Integer;
theTriangles : ArrayOfTriangles from Graphic3d;
theIsReflected : Boolean;
theIsShrinked : Boolean;
theShrinkCoef : Real;
theIsMeshSmoothShading : Boolean
) is protected;
---Purpose: Add to array of polygons a polygon representing face
@@ -120,10 +123,10 @@ is
---Purpose: Calculate how many polygons or polylines are necessary to draw passed topology
DrawArrays ( me; Prs : Presentation from Prs3d;
thePolygons : ArrayOfPolygons from Graphic3d;
theLines : ArrayOfPolylines from Graphic3d;
theLinkLines : ArrayOfPolylines from Graphic3d;
theVolumesInShad : ArrayOfPolygons from Graphic3d;
thePolygons : ArrayOfPrimitives from Graphic3d;
theLines : ArrayOfPrimitives from Graphic3d;
theLinkLines : ArrayOfPrimitives from Graphic3d;
theVolumesInShad : ArrayOfPrimitives from Graphic3d;
IsPolygonsEdgesOff : Boolean;
IsSelected : Boolean;
theFillAsp : AspectFillArea3d from Graphic3d;

View File

@@ -24,6 +24,7 @@
#include <Graphic3d_AspectFillArea3d.hxx>
#include <Graphic3d_AspectMarker3d.hxx>
#include <Graphic3d_ArrayOfPolygons.hxx>
#include <Graphic3d_ArrayOfTriangles.hxx>
#include <Graphic3d_ArrayOfSegments.hxx>
#include <Graphic3d_ArrayOfPoints.hxx>
#include <Graphic3d_ArrayOfPolylines.hxx>
@@ -37,6 +38,7 @@
#include <TColStd_SequenceOfInteger.hxx>
#include <TColStd_PackedMapOfInteger.hxx>
#include <TColStd_HPackedMapOfInteger.hxx>
#include <TColStd_MapOfInteger.hxx>
#include <Quantity_NameOfColor.hxx>
#include <Aspect_InteriorStyle.hxx>
@@ -49,6 +51,10 @@
#include <MeshVS_DrawerAttribute.hxx>
#include <MeshVS_MapOfTwoNodes.hxx>
#include <MeshVS_Buffer.hxx>
#include <MeshVS_SymmetricPairHasher.hxx>
#include <NCollection_Map.hxx>
#include <NCollection_Vector.hxx>
//================================================================
// Function : Constructor MeshVS_MeshPrsBuilder
@@ -120,7 +126,7 @@ void MeshVS_MeshPrsBuilder::BuildNodes ( const Handle(Prs3d_Presentation)& Prs,
anIDs.Assign( IDs );
if ( !HasSelectFlag && !HasHilightFlag )
{
// subtract the hidden nodes and ids to exclude (to minimise allocated memory)
// subtract the hidden nodes and ids to exclude (to minimize allocated memory)
Handle(TColStd_HPackedMapOfInteger) aHiddenNodes = myParentMesh->GetHiddenNodes();
if ( !aHiddenNodes.IsNull() )
anIDs.Subtract( aHiddenNodes->Map() );
@@ -200,7 +206,7 @@ void MeshVS_MeshPrsBuilder::BuildElements( const Handle(Prs3d_Presentation)& Prs
IsReflect = ( IsMeshReflect && !HasHilightFlag );
aDrawer->GetBoolean ( MeshVS_DA_SmoothShading, IsMeshSmoothShading );
// display mode for hilighted prs of groups
// display mode for highlighted prs of groups
IsShrink = ( IsShrink && !HasHilightFlag );
IsShading = ( IsShading || HasHilightFlag );
@@ -221,14 +227,7 @@ void MeshVS_MeshPrsBuilder::BuildElements( const Handle(Prs3d_Presentation)& Prs
Standard_Boolean IsOverlapControl =
!IsMeshAllowOverlap && ( IsWireFrame || IsShading ) && !HasSelectFlag;
Handle (Graphic3d_ArrayOfPolygons) aPolygons, aVolumes;
Handle (Graphic3d_ArrayOfPolylines) aPolylines, aLinkPolylines;
Standard_Integer PolygonVerticesFor3D = 0, PolygonBoundsFor3D = 0,
PolylineVerticesFor3D = 0, PolylineBoundsFor3D = 0,
NbNodes;
// subtract the hidden elements and ids to exclude (to minimise allocated memory)
// subtract the hidden elements and ids to exclude (to minimize allocated memory)
TColStd_PackedMapOfInteger anIDs;
anIDs.Assign( IDs );
Handle(TColStd_HPackedMapOfInteger) aHiddenElems = myParentMesh->GetHiddenElems();
@@ -238,170 +237,260 @@ void MeshVS_MeshPrsBuilder::BuildElements( const Handle(Prs3d_Presentation)& Prs
Handle( MeshVS_HArray1OfSequenceOfInteger ) aTopo;
TColStd_MapIteratorOfPackedMapOfInteger it (anIDs);
for( ; it.More(); it.Next() )
Standard_Boolean showEdges = Standard_True;
aDrawer->GetBoolean( MeshVS_DA_ShowEdges, showEdges );
showEdges = IsWireFrame || showEdges;
Standard_Integer* aNodesBuf = (Standard_Integer*) alloca (maxnodes * sizeof (Standard_Integer));
Standard_Real* aCoordsBuf = (Standard_Real*) alloca (3 * maxnodes * sizeof (Standard_Real));
TColStd_Array1OfInteger aNodes (*aNodesBuf, 1, maxnodes);
TColStd_Array1OfReal aCoords (*aCoordsBuf, 1, 3 * maxnodes);
Standard_Integer aNbFacePrimitives = 0;
Standard_Integer aNbVolmPrimitives = 0;
Standard_Integer aNbEdgePrimitives = 0;
Standard_Integer aNbLinkPrimitives = 0;
MeshVS_EntityType aType;
for (it.Reset(); it.More(); it.Next())
{
Standard_Integer aKey = it.Key();
if( aSource->Get3DGeom( aKey, NbNodes, aTopo ) )
Standard_Integer aNbNodes = 0;
if (!aSource->GetGeom (it.Key(), Standard_True, aCoords, aNbNodes, aType))
continue;
if (aType == MeshVS_ET_Volume)
{
if (aSource->Get3DGeom (it.Key(), aNbNodes, aTopo))
{
for (Standard_Integer aFaceIdx = aTopo->Lower(); aFaceIdx <= aTopo->Upper(); ++aFaceIdx)
{
const TColStd_SequenceOfInteger& aFaceNodes = aTopo->Value (aFaceIdx);
if (showEdges) // add edge segments
{
aNbEdgePrimitives += aFaceNodes.Length();
}
if (IsShading || IsShrink) // add volumetric cell triangles
{
if (!HasSelectFlag)
HowManyPrimitives( aTopo, Standard_True, HasSelectFlag, NbNodes,
PolygonVerticesFor3D, PolygonBoundsFor3D );
HowManyPrimitives( aTopo, Standard_False, HasSelectFlag, NbNodes,
PolylineVerticesFor3D, PolylineBoundsFor3D );
aNbVolmPrimitives += aFaceNodes.Length() - 2;
}
}
}
}
else if (aType == MeshVS_ET_Link)
{
if (showEdges)
{
aNbLinkPrimitives += 1; // add link segment
}
}
else if (aType == MeshVS_ET_Face)
{
if (showEdges)
{
aNbEdgePrimitives += aNbNodes; // add edge segments
}
if (!IsOverlapControl || IsShading)
{
if ((IsShading || IsShrink) && !HasSelectFlag)
{
aNbFacePrimitives += aNbNodes - 2; // add face triangles
}
}
}
}
Standard_Integer Extent = anIDs.Extent();
// Here we do not use indices arrays because they are not effective for some mesh
// drawing modes: shrinking mode (displaces the vertices inside the polygon), 3D
// cell rendering (normal interpolation is not always applicable - flat shading),
// elemental coloring (color interpolation is impossible)
Handle (Graphic3d_ArrayOfTriangles) aVolmTriangles =
new Graphic3d_ArrayOfTriangles (aNbVolmPrimitives * 3, 0, IsReflect);
Handle (Graphic3d_ArrayOfTriangles) aFaceTriangles =
new Graphic3d_ArrayOfTriangles (aNbFacePrimitives * 3, 0, IsReflect);
if ( IsReflect )
Handle (Graphic3d_ArrayOfSegments) aLinkSegments;
Handle (Graphic3d_ArrayOfSegments) aEdgeSegments;
if (showEdges)
{
aPolygons = new Graphic3d_ArrayOfPolygons
( maxnodes*Extent, Extent, 0, Standard_True );
aVolumes = new Graphic3d_ArrayOfPolygons
( PolygonVerticesFor3D, PolygonBoundsFor3D, 0, Standard_True );
}
else
{
aPolygons = new Graphic3d_ArrayOfPolygons( maxnodes*Extent, Extent );
aVolumes = new Graphic3d_ArrayOfPolygons ( PolygonVerticesFor3D, PolygonBoundsFor3D );
aLinkSegments = new Graphic3d_ArrayOfSegments (aNbLinkPrimitives * 2);
aEdgeSegments = new Graphic3d_ArrayOfSegments (aNbEdgePrimitives * 2);
}
Standard_Integer howMany = 1;
if ( IsOverlapControl )
howMany = 2;
Standard_Boolean showEdges = Standard_True;
aDrawer->GetBoolean( MeshVS_DA_ShowEdges, showEdges );
showEdges = IsWireFrame || showEdges;
if ( showEdges )
{
aPolylines = new Graphic3d_ArrayOfPolylines ( ( maxnodes+1 )*Extent + PolylineVerticesFor3D,
howMany * Extent + PolylineBoundsFor3D );
aLinkPolylines = new Graphic3d_ArrayOfPolylines ( 2*Extent, Extent );
}
MeshVS_Buffer aCoordsBuf (3*maxnodes*sizeof(Standard_Real));
TColStd_Array1OfReal aCoords( aCoordsBuf, 1, 3*maxnodes );
MeshVS_EntityType aType;
TColStd_PackedMapOfInteger aCustomElements;
Quantity_Color anOldEdgeColor;
Quantity_Color anEdgeColor;
Quantity_Color anIntColor;
Aspect_InteriorStyle anIntType;
Quantity_Color anIntColor, anEdgeColor;
Aspect_TypeOfLine aLine;
Standard_Real aWidth;
MeshVS_TwoNodes aTwoNodes;
aFill->Values (anIntType, anIntColor, anEdgeColor, aLine, aWidth);
MeshVS_MapOfTwoNodes aLinkNodes;
// Forbid drawings of edges which overlap with some links
if (showEdges && IsOverlapControl)
// Forbid drawings of edges, which overlap with some links
{
for (it.Reset(); it.More(); it.Next())
{
Standard_Integer aKey = it.Key();
if ( aSource->GetGeomType ( aKey, Standard_True, aType ) &&
aType == MeshVS_ET_Link )
if (aSource->GetGeomType (it.Key(), Standard_True, aType) && aType == MeshVS_ET_Link)
{
MeshVS_Buffer aNodesBuf (maxnodes * sizeof(Standard_Integer));
TColStd_Array1OfInteger aNodes (aNodesBuf, 1, maxnodes);
Standard_Integer nbNodes;
if ( aSource->GetNodesByElement( aKey, aNodes, nbNodes ) &&
nbNodes == 2 )
Standard_Integer aNbNodes;
if (aSource->GetNodesByElement (it.Key(), aNodes, aNbNodes) && aNbNodes == 2)
{
aTwoNodes.First = aNodes(1);
aTwoNodes.Second = aNodes(2);
aLinkNodes.Add ( aTwoNodes );
aLinkNodes.Add (MeshVS_TwoNodes (aNodes(1), aNodes(2)));
}
}
}
}
NCollection_Map<MeshVS_NodePair, MeshVS_SymmetricPairHasher> aSegmentMap;
for (it.Reset(); it.More(); it.Next())
{
Standard_Integer aKey = it.Key();
const Standard_Integer aKey = it.Key();
Standard_Integer NbNodes;
if (!aSource->GetGeom (aKey, Standard_True, aCoords, NbNodes, aType))
continue;
if (!aSource->GetNodesByElement (aKey, aNodes, NbNodes))
continue;
switch (aType)
{
case MeshVS_ET_Volume:
{
if (IsExcludingOn())
IDsToExclude.Add (aKey);
if (aSource->Get3DGeom (aKey, NbNodes, aTopo))
{
// !!! TO DO: Overlap control
// add wireframe presentation (draw edges for shading mode as well)
// Add wire-frame presentation (draw edges for shading mode as well)
if (showEdges)
AddVolumePrs ( aTopo, aCoords, NbNodes, aPolylines, IsReflect, IsShrink, HasSelectFlag, aShrinkCoef );
{
AddVolumePrs (aTopo, aCoords, NbNodes,
aEdgeSegments, IsReflect, IsShrink, HasSelectFlag, aShrinkCoef);
}
// add shading presentation
// Add shading presentation
if ((IsShading || IsShrink) && !HasSelectFlag)
AddVolumePrs ( aTopo, aCoords, NbNodes, aVolumes, IsReflect, IsShrink, HasSelectFlag, aShrinkCoef );
{
AddVolumePrs (aTopo, aCoords, NbNodes,
aVolmTriangles, IsReflect, IsShrink, HasSelectFlag, aShrinkCoef);
}
}
}
break;
case MeshVS_ET_Link:
{
if (IsExcludingOn())
IDsToExclude.Add (aKey);
if (showEdges)
AddLinkPrs ( aCoords, aLinkPolylines, IsShrink || HasSelectFlag, aShrinkCoef );
{
AddLinkPrs (aCoords, aLinkSegments, IsShrink || HasSelectFlag, aShrinkCoef);
}
}
break;
case MeshVS_ET_Face:
{
if (IsExcludingOn())
IDsToExclude.Add (aKey);
if (showEdges && IsOverlapControl)
{
MeshVS_Buffer aNodesBuf (NbNodes * sizeof(Standard_Integer));
TColStd_Array1OfInteger aNodes (aNodesBuf, 1, NbNodes);
if ( !aSource->GetNodesByElement( aKey, aNodes, NbNodes ) )
continue;
Standard_Integer Last = 0;
for ( Standard_Integer i=1; i<=NbNodes; i++ )
MeshVS_TwoNodes aTwoNodes (aNodes (1));
for (Standard_Integer i = 1; i <= NbNodes; ++i)
{
if ( i==1 )
aTwoNodes.First = aNodes(i);
else
if (i > 1)
aTwoNodes.First = aTwoNodes.Second;
aTwoNodes.Second = ( i<NbNodes ? aNodes(i+1) : aNodes(1) );
aTwoNodes.Second = (i < NbNodes) ? aNodes (i+1) : aNodes (1);
if (aLinkNodes.Contains (aTwoNodes))
{
aPolylines->AddBound ( i-Last );
for (Standard_Integer j = Last+1; j<=i; j++)
aPolylines->AddVertex ( aCoords(3*j-2), aCoords(3*j-1), aCoords(3*j) );
for (Standard_Integer aNodeIdx = Last + 1; aNodeIdx < i; ++aNodeIdx)
{
const Standard_Integer aNextIdx = aNodeIdx + 1;
aEdgeSegments->AddVertex (
aCoords (3 * aNodeIdx - 2), aCoords (3 * aNodeIdx - 1), aCoords (3 * aNodeIdx));
aEdgeSegments->AddVertex (
aCoords (3 * aNextIdx - 2), aCoords (3 * aNextIdx - 1), aCoords (3 * aNextIdx));
}
Last = i;
}
}
if (NbNodes - Last > 0)
{
aPolylines->AddBound ( NbNodes-Last+1 );
for (Standard_Integer j = Last+1; j<=NbNodes; j++)
aPolylines->AddVertex ( aCoords(3*j-2), aCoords(3*j-1), aCoords(3*j) );
for (Standard_Integer aNodeIdx = Last; aNodeIdx < NbNodes; ++aNodeIdx)
{
const Standard_Integer aNextIdx = (aNodeIdx + 1) % NbNodes;
aPolylines->AddVertex ( aCoords(1), aCoords(2), aCoords(3) );
const MeshVS_NodePair aSegment (aNodes (aNodeIdx + 1),
aNodes (aNextIdx + 1));
if (!aSegmentMap.Contains (aSegment))
{
aEdgeSegments->AddVertex (aCoords (3 * aNodeIdx + 1),
aCoords (3 * aNodeIdx + 2),
aCoords (3 * aNodeIdx + 3));
aEdgeSegments->AddVertex (aCoords (3 * aNextIdx + 1),
aCoords (3 * aNextIdx + 2),
aCoords (3 * aNextIdx + 3));
aSegmentMap.Add (aSegment);
}
}
}
}
if (!IsOverlapControl || IsShading)
{
if (!IsOverlapControl && showEdges)
AddFaceWirePrs(aCoords, NbNodes, aPolylines,
IsShrink || HasSelectFlag, aShrinkCoef );
{
AddFaceWirePrs (aCoords, NbNodes,
aEdgeSegments, IsShrink || HasSelectFlag, aShrinkCoef);
}
if ((IsShading || IsShrink) && !HasSelectFlag)
AddFaceSolidPrs(aKey, aCoords, NbNodes, maxnodes, aPolygons,
IsReflect, IsShrink || HasSelectFlag,
aShrinkCoef, IsMeshSmoothShading );
{
AddFaceSolidPrs (aKey, aCoords, NbNodes, maxnodes, aFaceTriangles, IsReflect,
IsShrink || HasSelectFlag, aShrinkCoef, IsMeshSmoothShading);
}
}
}
break;
default:
{
aCustomElements.Add (aKey);
break;
}
}
}
@@ -411,7 +500,13 @@ void MeshVS_MeshPrsBuilder::BuildElements( const Handle(Prs3d_Presentation)& Prs
aFill->SetEdgeColor (Quantity_NOC_BLACK);
}
DrawArrays ( Prs, aPolygons, aPolylines, aLinkPolylines, aVolumes,
//std::cout << "Actual extents: " << std::endl
// << "Face tris: " << aFaceTriangles->ItemNumber() << " from " << aNbFacePrimitives << std::endl
// << "Volm tris: " << aVolmTriangles->ItemNumber() << " from " << aNbVolmPrimitives << std::endl
// << "Face segs: " << aEdgeSegments->ItemNumber() << " from " << aNbEdgePrimitives << std::endl
// << "Link segs: " << aLinkSegments->ItemNumber() << " from " << aNbLinkPrimitives << std::endl;
DrawArrays ( Prs, aFaceTriangles, aEdgeSegments, aLinkSegments, aVolmTriangles,
!showEdges, HasSelectFlag, aFill, aBeam );
if ( !aCustomElements.IsEmpty() )
@@ -543,33 +638,34 @@ void MeshVS_MeshPrsBuilder::BuildHilightPrs ( const Handle(Prs3d_Presentation)&
// Purpose :
//================================================================
void MeshVS_MeshPrsBuilder::AddLinkPrs (const TColStd_Array1OfReal& theCoords,
const Handle(Graphic3d_ArrayOfPolylines)& theLines,
const Standard_Boolean IsShrinked,
const Standard_Real ShrinkCoef) const
const Handle(Graphic3d_ArrayOfSegments)& theSegments,
const Standard_Boolean theIsShrinked,
const Standard_Real theShrinkCoef) const
{
Standard_Real x1 = theCoords(1);
Standard_Real y1 = theCoords(2);
Standard_Real z1 = theCoords(3);
Standard_Real x2 = theCoords(4);
Standard_Real y2 = theCoords(5);
Standard_Real z2 = theCoords(6);
Standard_Real xG, yG, zG;
Standard_Real aX1 = theCoords (1);
Standard_Real aY1 = theCoords (2);
Standard_Real aZ1 = theCoords (3);
Standard_Real aX2 = theCoords (4);
Standard_Real aY2 = theCoords (5);
Standard_Real aZ2 = theCoords (6);
if ( IsShrinked )
if (theIsShrinked)
{
xG = (x1+x2)/2.0;
yG = (y1+y2)/2.0;
zG = (z1+z2)/2.0;
x1 = (x1 - xG) * ShrinkCoef + xG;
x2 = 2.0*xG - x1;
y1 = (y1 - yG) * ShrinkCoef + yG;
y2 = 2.0*yG - y1;
z1 = (z1 - zG) * ShrinkCoef + zG;
z2 = 2.0*zG - z1;
const Standard_Real xG = (aX1 + aX2) * 0.5;
const Standard_Real yG = (aY1 + aY2) * 0.5;
const Standard_Real zG = (aZ1 + aZ2) * 0.5;
aX1 = (aX1 - xG) * theShrinkCoef + xG;
aY1 = (aY1 - yG) * theShrinkCoef + yG;
aZ1 = (aZ1 - zG) * theShrinkCoef + zG;
aX2 = 2.0 * xG - aX1;
aY2 = 2.0 * yG - aY1;
aZ2 = 2.0 * zG - aZ1;
}
theLines->AddBound ( 2 );
theLines->AddVertex ( x1, y1, z1 );
theLines->AddVertex ( x2, y2, z2 );
theSegments->AddVertex (aX1, aY1, aZ1);
theSegments->AddVertex (aX2, aY2, aZ2);
}
//================================================================
@@ -577,91 +673,150 @@ void MeshVS_MeshPrsBuilder::AddLinkPrs (const TColStd_Array1OfReal& theCoords,
// Purpose :
//================================================================
void MeshVS_MeshPrsBuilder::AddFaceWirePrs (const TColStd_Array1OfReal& theCoords,
const Standard_Integer NbNodes,
const Handle(Graphic3d_ArrayOfPolylines)& theLines,
const Standard_Boolean IsShrinked,
const Standard_Real ShrinkCoef) const
const Standard_Integer theNbNodes,
const Handle(Graphic3d_ArrayOfSegments)& theSegments,
const Standard_Boolean theIsShrinked,
const Standard_Real theShrinkingCoef) const
{
Standard_Real xG = 0., yG = 0., zG = 0., X, Y, Z, startX=0., startY=0., startZ=0.;
theLines->AddBound ( NbNodes+1 );
if ( IsShrinked )
CalculateCenter( theCoords, NbNodes, xG, yG, zG );
Standard_Real aCenterX = 0.0;
Standard_Real aCenterY = 0.0;
Standard_Real aCenterZ = 0.0;
for ( Standard_Integer k=1; k<=NbNodes; k++)
if (theIsShrinked)
{
X = theCoords(3*k-2);
Y = theCoords(3*k-1);
Z = theCoords(3*k);
if ( IsShrinked )
CalculateCenter (theCoords, theNbNodes, aCenterX, aCenterY, aCenterZ);
}
NCollection_Vector<gp_XYZ> aNodes (theNbNodes);
for (Standard_Integer aNodeIdx = 0; aNodeIdx < theNbNodes; ++aNodeIdx)
{
X = (X - xG) * ShrinkCoef + xG;
Y = (Y - yG) * ShrinkCoef + yG;
Z = (Z - zG) * ShrinkCoef + zG;
}
if( k==1 )
gp_XYZ aPnt (theCoords (3 * aNodeIdx + 1),
theCoords (3 * aNodeIdx + 2),
theCoords (3 * aNodeIdx + 3));
if (theIsShrinked)
{
startX = X; startY = Y; startZ = Z;
aPnt.SetX ((aPnt.X() - aCenterX) * theShrinkingCoef + aCenterX);
aPnt.SetY ((aPnt.Y() - aCenterY) * theShrinkingCoef + aCenterY);
aPnt.SetZ ((aPnt.Z() - aCenterZ) * theShrinkingCoef + aCenterZ);
}
theLines->AddVertex ( X, Y, Z );
aNodes.Append (aPnt);
}
for (Standard_Integer aNodeIdx = 0; aNodeIdx < theNbNodes; ++aNodeIdx)
{
theSegments->AddVertex (aNodes.Value (aNodeIdx).X(),
aNodes.Value (aNodeIdx).Y(),
aNodes.Value (aNodeIdx).Z());
const Standard_Integer aNextIdx = (aNodeIdx + 1) % theNbNodes;
theSegments->AddVertex (aNodes.Value (aNextIdx).X(),
aNodes.Value (aNextIdx).Y(),
aNodes.Value (aNextIdx).Z());
}
theLines->AddVertex( startX, startY, startZ );
}
//================================================================
// Function : AddFaceSolidPrs
// Purpose :
//================================================================
void MeshVS_MeshPrsBuilder::AddFaceSolidPrs (const Standard_Integer ID,
void MeshVS_MeshPrsBuilder::AddFaceSolidPrs (const Standard_Integer theID,
const TColStd_Array1OfReal& theCoords,
const Standard_Integer NbNodes,
const Standard_Integer MaxNodes,
const Handle(Graphic3d_ArrayOfPolygons)& thePolygons,
const Standard_Boolean IsReflected,
const Standard_Boolean IsShrinked,
const Standard_Real ShrinkCoef,
const Standard_Boolean IsMeshSmoothShading) const
const Standard_Integer theNbNodes,
const Standard_Integer theMaxNodes,
const Handle(Graphic3d_ArrayOfTriangles)& theTriangles,
const Standard_Boolean theIsShaded,
const Standard_Boolean theIsShrinked,
const Standard_Real theShrinkingCoef,
const Standard_Boolean theIsSmoothShading) const
{
Handle( MeshVS_DataSource ) aDS = myParentMesh->GetDataSource();
if ( aDS.IsNull() )
Handle(MeshVS_DataSource) aDataSource = myParentMesh->GetDataSource();
if (aDataSource.IsNull())
return;
Standard_Real xG = 0., yG = 0., zG = 0., X, Y, Z, nx = 0., ny = 0., nz = 0.;
thePolygons->AddBound ( NbNodes );
if ( IsShrinked )
CalculateCenter( theCoords, NbNodes, xG, yG, zG );
Standard_Real aCenterX = 0.0;
Standard_Real aCenterY = 0.0;
Standard_Real aCenterZ = 0.0;
Standard_Real aNormalX = 0.0;
Standard_Real aNormalY = 0.0;
Standard_Real aNormalZ = 0.0;
Standard_Boolean allNormals = Standard_True;
Standard_Integer k;
if( IsReflected )
if (theIsShrinked)
{
if( IsMeshSmoothShading )
for( k=1; k<=NbNodes && allNormals; k++ )
allNormals = aDS->GetNodeNormal (k, ID, nx, ny, nz);
if( !IsMeshSmoothShading || !allNormals )
aDS->GetNormal( ID, MaxNodes, nx, ny, nz );
CalculateCenter (theCoords, theNbNodes, aCenterX, aCenterY, aCenterZ);
}
for ( k=1; k<=NbNodes; k++)
NCollection_Vector<gp_XYZ> aVertexNormals (theMaxNodes);
if (theIsShaded)
{
X = theCoords(3*k-2);
Y = theCoords(3*k-1);
Z = theCoords(3*k);
if ( IsShrinked )
if (theIsSmoothShading)
{
X = (X - xG) * ShrinkCoef + xG;
Y = (Y - yG) * ShrinkCoef + yG;
Z = (Z - zG) * ShrinkCoef + zG;
for (Standard_Integer aNodeIdx = 1; aNodeIdx <= theNbNodes; ++aNodeIdx)
{
if (!aDataSource->GetNodeNormal (aNodeIdx, theID, aNormalX, aNormalY, aNormalZ))
break;
aVertexNormals.Append (gp_XYZ (aNormalX, aNormalY, aNormalZ));
}
}
if ( IsReflected )
if (!theIsSmoothShading || aVertexNormals.Size() != theNbNodes)
{
if( IsMeshSmoothShading && allNormals )
aDS->GetNodeNormal (k, ID, nx, ny, nz);
thePolygons->AddVertex ( X, Y, Z, nx, ny, nz );
aDataSource->GetNormal (theID, theMaxNodes, aNormalX, aNormalY, aNormalZ);
}
}
NCollection_Vector<gp_XYZ> aNodes (theMaxNodes);
for (Standard_Integer aNodeIdx = 0; aNodeIdx < theNbNodes; ++aNodeIdx)
{
gp_XYZ aPnt (theCoords (3 * aNodeIdx + 1),
theCoords (3 * aNodeIdx + 2),
theCoords (3 * aNodeIdx + 3));
if (theIsShrinked)
{
aPnt.SetX ((aPnt.X() - aCenterX) * theShrinkingCoef + aCenterX);
aPnt.SetY ((aPnt.Y() - aCenterY) * theShrinkingCoef + aCenterY);
aPnt.SetZ ((aPnt.Z() - aCenterZ) * theShrinkingCoef + aCenterZ);
}
aNodes.Append (aPnt);
}
// Triangulate polygon
for (Standard_Integer aNodeIdx = 0; aNodeIdx < theNbNodes - 2; ++aNodeIdx)
{
for (Standard_Integer aSubIdx = 0; aSubIdx < 3; ++aSubIdx)
{
if (theIsShaded)
{
if (theIsSmoothShading && aVertexNormals.Size() == theNbNodes)
{
aNormalX = aVertexNormals.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).X();
aNormalY = aVertexNormals.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).Y();
aNormalZ = aVertexNormals.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).Z();
}
theTriangles->AddVertex (aNodes.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).X(),
aNodes.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).Y(),
aNodes.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).Z(),
aNormalX,
aNormalY,
aNormalZ);
}
else
thePolygons->AddVertex ( X, Y, Z );
{
theTriangles->AddVertex (aNodes.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).X(),
aNodes.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).Y(),
aNodes.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).Z());
}
}
}
}
@@ -669,171 +824,178 @@ void MeshVS_MeshPrsBuilder::AddFaceSolidPrs (const Standard_Integer ID,
// Function : AddVolumePrs
// Purpose :
//================================================================
void MeshVS_MeshPrsBuilder::AddVolumePrs (const Handle( MeshVS_HArray1OfSequenceOfInteger )& Topo,
const TColStd_Array1OfReal& Nodes,
const Standard_Integer NbNodes,
const Handle( Graphic3d_ArrayOfPrimitives )& Array,
const Standard_Boolean IsReflected,
const Standard_Boolean IsShrinked,
const Standard_Boolean IsSelect,
const Standard_Real ShrinkCoef)
void MeshVS_MeshPrsBuilder::AddVolumePrs (const Handle(MeshVS_HArray1OfSequenceOfInteger)& theTopo,
const TColStd_Array1OfReal& theNodes,
const Standard_Integer theNbNodes,
const Handle(Graphic3d_ArrayOfPrimitives)& theArray,
const Standard_Boolean theIsShaded,
const Standard_Boolean theIsShrinked,
const Standard_Boolean theIsSelected,
const Standard_Real theShrinkCoef)
{
Standard_Real c[3]; c[0] = c[1] = c[2] = 0.0;
Standard_Integer low = Nodes.Lower(), n=NbNodes;
Standard_Real aCenter[] = { 0.0, 0.0, 0.0 };
if( Topo.IsNull() || Array.IsNull() )
Standard_Integer aLow = theNodes.Lower();
if (theTopo.IsNull() || theArray.IsNull())
return;
if( IsShrinked )
if (theIsShrinked)
{
for( Standard_Integer i=0; i<3*n; i++ )
c[i%3] += Nodes.Value( low + i );
c[0] /= n;
c[1] /= n;
c[2] /= n;
for (Standard_Integer aNodeIdx = 0; aNodeIdx < 3 * theNbNodes; ++aNodeIdx)
{
aCenter[aNodeIdx % 3] += theNodes.Value (aLow + aNodeIdx);
}
Standard_Boolean IsPolygons = Array->IsKind( STANDARD_TYPE( Graphic3d_ArrayOfPolygons ) );
Standard_Real x[2], y[2], z[2];
Standard_Integer ind;
gp_Vec norm;
if( IsPolygons )
{
for( Standard_Integer i=Topo->Lower(), topoup=Topo->Upper(); i<=topoup; i++ )
{
const TColStd_SequenceOfInteger& aSeq = Topo->Value( i );
Standard_Integer m = aSeq.Length();
Array->AddBound( m );
norm.SetCoord( 0, 0, 0 );
if( IsReflected )
{
MeshVS_Buffer PolyNodesBuf (3*m*sizeof(Standard_Real));
TColStd_Array1OfReal PolyNodes( PolyNodesBuf, 0, 3*m );
PolyNodes.SetValue( 0, m );
for( Standard_Integer j=1; j<=m; j++ )
{
ind = aSeq.Value( j );
PolyNodes.SetValue( 3*j-2, Nodes.Value( low+3*ind ) );
PolyNodes.SetValue( 3*j-1, Nodes.Value( low+3*ind+1 ) );
PolyNodes.SetValue( 3*j, Nodes.Value( low+3*ind+2 ) );
aCenter[0] /= theNbNodes;
aCenter[1] /= theNbNodes;
aCenter[2] /= theNbNodes;
}
// compute normal
// if( !MeshVS_Tool::GetNormal( PolyNodes, norm ) )
// norm.SetCoord( 0, 0, 0 );
MeshVS_Tool::GetAverageNormal( PolyNodes, norm );
Standard_Boolean aIsPolygons = theArray->IsKind (STANDARD_TYPE (Graphic3d_ArrayOfTriangles));
if (aIsPolygons)
{
for (Standard_Integer aFaceIdx = theTopo->Lower(), topoup = theTopo->Upper(); aFaceIdx <= topoup; ++aFaceIdx)
{
const TColStd_SequenceOfInteger& aFaceNodes = theTopo->Value (aFaceIdx);
const Standard_Integer aNbPolyNodes = aFaceNodes.Length();
Standard_Real* aPolyNodesBuf = (Standard_Real*) alloca ((3 * aNbPolyNodes + 1) * sizeof (Standard_Real));
TColStd_Array1OfReal aPolyNodes (*aPolyNodesBuf, 0, 3 * aNbPolyNodes);
for (Standard_Integer aNodeIdx = 0; aNodeIdx < aNbPolyNodes; ++aNodeIdx)
{
Standard_Integer anIdx = aFaceNodes.Value (aNodeIdx + 1);
Standard_Real aX = theNodes.Value (aLow + 3 * anIdx + 0);
Standard_Real aY = theNodes.Value (aLow + 3 * anIdx + 1);
Standard_Real aZ = theNodes.Value (aLow + 3 * anIdx + 2);
if (theIsShrinked)
{
aX = aCenter[0] + theShrinkCoef * (aX - aCenter[0]);
aY = aCenter[1] + theShrinkCoef * (aY - aCenter[1]);
aZ = aCenter[2] + theShrinkCoef * (aZ - aCenter[2]);
}
Standard_Real nx = norm.X(), ny = norm.Y(), nz = norm.Z();
for( Standard_Integer j=1; j<=m; j++ )
{
ind = aSeq.Value( j );
x[0] = Nodes.Value( low + 3*ind );
y[0] = Nodes.Value( low + 3*ind+1 );
z[0] = Nodes.Value( low + 3*ind+2 );
if( IsShrinked )
{
x[0] = c[0] + ShrinkCoef * ( x[0]-c[0] );
y[0] = c[1] + ShrinkCoef * ( y[0]-c[1] );
z[0] = c[2] + ShrinkCoef * ( z[0]-c[2] );
aPolyNodes.SetValue (3 * aNodeIdx + 1, aX);
aPolyNodes.SetValue (3 * aNodeIdx + 2, aY);
aPolyNodes.SetValue (3 * aNodeIdx + 3, aZ);
}
if( IsReflected )
Array->AddVertex( x[0], y[0], z[0], nx, ny, nz );
gp_Vec aNorm;
if (theIsShaded)
{
aPolyNodes.SetValue (0, aNbPolyNodes);
if (!MeshVS_Tool::GetAverageNormal (aPolyNodes, aNorm))
{
aNorm.SetCoord (0.0, 0.0, 1.0);
}
}
for (Standard_Integer aNodeIdx = 0; aNodeIdx < aNbPolyNodes - 2; ++aNodeIdx) // triangulate polygon
{
for (Standard_Integer aSubIdx = 0; aSubIdx < 3; ++aSubIdx) // generate sub-triangle
{
if (theIsShaded)
{
theArray->AddVertex (aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 1),
aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 2),
aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 3),
aNorm.X(),
aNorm.Y(),
aNorm.Z());
}
else
Array->AddVertex( x[0], y[0], z[0] );
}
}
}
else if( IsSelect )
{
for( Standard_Integer i=Topo->Lower(), topoup=Topo->Upper(); i<=topoup; i++ )
{
const TColStd_SequenceOfInteger& aSeq = Topo->Value( i );
Standard_Real pc[3]; pc[0] = pc[1] = pc[2] = 0;
Standard_Integer j,m;
for( j=1, m=aSeq.Length(); j<=m; j++ )
{
ind = aSeq.Value( j );
for( Standard_Integer k=0; k<3; k++ )
pc[k] += Nodes.Value( low + 3*ind+k );
theArray->AddVertex (aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 1),
aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 2),
aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 3));
}
pc[0] /= m;
pc[1] /= m;
pc[2] /= m;
}
}
}
}
else if (theIsSelected)
{
for (Standard_Integer aFaceIdx = theTopo->Lower(), topoup = theTopo->Upper(); aFaceIdx <= topoup; ++aFaceIdx)
{
const TColStd_SequenceOfInteger& aFaceNodes = theTopo->Value (aFaceIdx);
Array->AddBound( m+1 );
for( j=1, m=aSeq.Length(); j<=m+1; j++ )
Standard_Real aFaceCenter[] = { 0.0, 0.0, 0.0 };
for (Standard_Integer aNodeIdx = 1; aNodeIdx <= aFaceNodes.Length(); ++aNodeIdx)
{
ind = aSeq.Value( (j-1)%m + 1 );
x[0] = Nodes.Value( low + 3*ind );
y[0] = Nodes.Value( low + 3*ind+1 );
z[0] = Nodes.Value( low + 3*ind+2 );
x[0] = pc[0] + ShrinkCoef * ( x[0]-pc[0] );
y[0] = pc[1] + ShrinkCoef * ( y[0]-pc[1] );
z[0] = pc[2] + ShrinkCoef * ( z[0]-pc[2] );
Array->AddVertex( x[0], y[0], z[0] );
for (Standard_Integer aAxisIdx = 0; aAxisIdx < 3; ++aAxisIdx)
{
aFaceCenter[aAxisIdx] += theNodes.Value (aLow + 3 * aFaceNodes.Value (aNodeIdx) + aAxisIdx);
}
}
aFaceCenter[0] /= aFaceNodes.Length();
aFaceCenter[1] /= aFaceNodes.Length();
aFaceCenter[2] /= aFaceNodes.Length();
for (Standard_Integer aNodeIdx = 0, aNbNodes = aFaceNodes.Length(); aNodeIdx < aNbNodes; ++aNodeIdx)
{
for (Standard_Integer aSubIdx = 0; aSubIdx < 2; ++aSubIdx) // add segment
{
Standard_Integer anIdx = aFaceNodes.Value ((aNodeIdx + aSubIdx) % aNbNodes + 1);
Standard_Real aX = theNodes.Value (aLow + 3 * anIdx + 0);
Standard_Real aY = theNodes.Value (aLow + 3 * anIdx + 1);
Standard_Real aZ = theNodes.Value (aLow + 3 * anIdx + 2);
theArray->AddVertex (aFaceCenter[0] + theShrinkCoef * (aX - aFaceCenter[0]),
aFaceCenter[1] + theShrinkCoef * (aY - aFaceCenter[1]),
aFaceCenter[2] + theShrinkCoef * (aZ - aFaceCenter[2]));
}
}
}
}
else
{
Standard_Integer F, S=0, k;
// Find all pairs of nodes (edges) to draw (will be drawn only once)
NCollection_Map<MeshVS_NodePair, MeshVS_SymmetricPairHasher> aEdgeMap;
// Find all pairs of nodes (edges) to draw;
// map is used to ensure that each edge will be drawn only once
TColStd_PackedMapOfInteger aMap;
for( Standard_Integer i=Topo->Lower(), topoup=Topo->Upper(); i<=topoup; i++ )
for (Standard_Integer aFaceIdx = theTopo->Lower(), topoup = theTopo->Upper(); aFaceIdx <= topoup; ++aFaceIdx)
{
const TColStd_SequenceOfInteger& aSeq = Topo->Value( i );
for( Standard_Integer j=1, m=aSeq.Length(); j<=m; j++ )
const TColStd_SequenceOfInteger& aFaceNodes = theTopo->Value (aFaceIdx);
for (Standard_Integer aNodeIdx = 0, aNbNodes = aFaceNodes.Length(); aNodeIdx < aNbNodes; ++aNodeIdx)
{
if( j==1 )
F = aSeq.Value( j );
else
F = S;
const Standard_Integer aNextIdx = (aNodeIdx + 1) % aNbNodes;
S = j<m ? aSeq.Value( j+1 ) : aSeq.Value( 1 );
if( F<S )
aMap.Add( F + NbNodes * S );
else
aMap.Add( S + NbNodes * F );
aEdgeMap.Add (MeshVS_NodePair (aFaceNodes.Value (aNodeIdx + 1),
aFaceNodes.Value (aNextIdx + 1)));
}
}
// draw edges
TColStd_MapIteratorOfPackedMapOfInteger anIt( aMap );
for( ; anIt.More(); anIt.Next() )
// Draw edges
for(NCollection_Map<MeshVS_NodePair, MeshVS_SymmetricPairHasher>::Iterator anIt (aEdgeMap); anIt.More(); anIt.Next())
{
F = low + 3*(anIt.Key()%NbNodes);
S = low + 3*(anIt.Key()/NbNodes);
const Standard_Integer anIdx1 = aLow + 3 * anIt.Key().first;
const Standard_Integer anIdx2 = aLow + 3 * anIt.Key().second;
x[0] = Nodes.Value( F );
y[0] = Nodes.Value( F+1 );
z[0] = Nodes.Value( F+2 );
x[1] = Nodes.Value( S );
y[1] = Nodes.Value( S+1 );
z[1] = Nodes.Value( S+2 );
Standard_Real aX[] = { theNodes.Value (anIdx1 + 0), theNodes.Value (anIdx2 + 0) };
Standard_Real aY[] = { theNodes.Value (anIdx1 + 1), theNodes.Value (anIdx2 + 1) };
Standard_Real aZ[] = { theNodes.Value (anIdx1 + 2), theNodes.Value (anIdx2 + 2) };
if( IsShrinked )
for( k=0; k<2; k++ )
if (theIsShrinked)
{
x[k] = c[0] + ShrinkCoef * ( x[k]-c[0] );
y[k] = c[1] + ShrinkCoef * ( y[k]-c[1] );
z[k] = c[2] + ShrinkCoef * ( z[k]-c[2] );
for (Standard_Integer anAxisIdx = 0; anAxisIdx < 2; ++anAxisIdx)
{
aX[anAxisIdx] = aCenter[0] + theShrinkCoef * (aX[anAxisIdx] - aCenter[0]);
aY[anAxisIdx] = aCenter[1] + theShrinkCoef * (aY[anAxisIdx] - aCenter[1]);
aZ[anAxisIdx] = aCenter[2] + theShrinkCoef * (aZ[anAxisIdx] - aCenter[2]);
}
}
Array->AddBound( 2 );
Array->AddVertex( x[0], y[0], z[0] );
Array->AddVertex( x[1], y[1], z[1] );
theArray->AddVertex (aX[0], aY[0], aZ[0]);
theArray->AddVertex (aX[1], aY[1], aZ[1]);
}
}
}
@@ -877,10 +1039,10 @@ void MeshVS_MeshPrsBuilder::HowManyPrimitives (const Handle(MeshVS_HArray1OfSequ
// Purpose :
//================================================================
void MeshVS_MeshPrsBuilder::DrawArrays( const Handle(Prs3d_Presentation)& Prs,
const Handle(Graphic3d_ArrayOfPolygons)& thePolygons,
const Handle(Graphic3d_ArrayOfPolylines)& theLines,
const Handle(Graphic3d_ArrayOfPolylines)& theLinkLines,
const Handle(Graphic3d_ArrayOfPolygons)& theVolumesInShad,
const Handle(Graphic3d_ArrayOfPrimitives)& thePolygons,
const Handle(Graphic3d_ArrayOfPrimitives)& theLines,
const Handle(Graphic3d_ArrayOfPrimitives)& theLinkLines,
const Handle(Graphic3d_ArrayOfPrimitives)& theVolumesInShad,
const Standard_Boolean IsPolygonsEdgesOff,
const Standard_Boolean IsSelected,
const Handle(Graphic3d_AspectFillArea3d)& theFillAsp,

View File

@@ -41,11 +41,15 @@ uses
DataSource from MeshVS,
DataMapOfIntegerColor from MeshVS,
BuilderPriority from MeshVS,
HArray1OfSequenceOfInteger from MeshVS,
SequenceOfColor from Aspect,
Color from Quantity,
DataMapOfIntegerReal from TColStd,
Texture2D from Graphic3d,
PackedMapOfInteger from TColStd
ArrayOfPrimitives from Graphic3d,
DataMapOfIntegerReal from TColStd,
PackedMapOfInteger from TColStd,
Array1OfInteger from TColStd,
Array1OfReal from TColStd
is
@@ -123,6 +127,16 @@ is
---Purpose: Create texture in accordance with myTextureColorMap
is static private;
AddVolumePrs ( me;
theTopo : HArray1OfSequenceOfInteger from MeshVS;
theNodes : Array1OfInteger from TColStd;
theCoords : Array1OfReal from TColStd;
theArray : ArrayOfPrimitives from Graphic3d;
theIsShaded : Boolean;
theNbColors : Integer;
theNbTexColors : Integer;
theColorRatio : Real );
---Purpose: Add to array polygons or polylines representing volume
fields
myNodeColorMap : DataMapOfIntegerColor from MeshVS;

View File

@@ -22,6 +22,8 @@
#include <Graphic3d_AspectLine3d.hxx>
#include <Graphic3d_ArrayOfPolygons.hxx>
#include <Graphic3d_ArrayOfPolylines.hxx>
#include <Graphic3d_ArrayOfSegments.hxx>
#include <Graphic3d_ArrayOfTriangles.hxx>
#include <Graphic3d_Group.hxx>
#include <Graphic3d_TextureParams.hxx>
@@ -45,6 +47,8 @@
#include <MeshVS_MeshPrsBuilder.hxx>
#include <MeshVS_HArray1OfSequenceOfInteger.hxx>
#include <MeshVS_Buffer.hxx>
#include <MeshVS_Tool.hxx>
#include <MeshVS_SymmetricPairHasher.hxx>
#include <gp_Pnt.hxx>
#include <Image_PixMap.hxx>
@@ -56,6 +60,9 @@
#include <Quantity_Array1OfColor.hxx>
#include <Aspect_SequenceOfColor.hxx>
#include <NCollection_Map.hxx>
#include <NCollection_Vector.hxx>
/*
Class : MeshVS_ImageTexture2D
Description : Texture for nodal presentation
@@ -146,7 +153,7 @@ void MeshVS_NodalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)& Prs,
(!myUseTexture && !myNodeColorMap.Extent()) )
return;
// subtract the hidden elements and ids to exclude (to minimise allocated memory)
// subtract the hidden elements and ids to exclude (to minimize allocated memory)
TColStd_PackedMapOfInteger anIDs;
anIDs.Assign( IDs );
Handle(TColStd_HPackedMapOfInteger) aHiddenElems = myParentMesh->GetHiddenElems();
@@ -223,10 +230,54 @@ void MeshVS_NodalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)& Prs,
( aMaxFaceNodes * aSize + PolygonVerticesFor3D, aSize + PolygonBoundsFor3D,
0, myUseTexture || IsReflect, !myUseTexture, Standard_False, myUseTexture );
Standard_Integer aNbFacePrimitives = 0;
Standard_Integer aNbVolmPrimitives = 0;
Standard_Integer aNbEdgePrimitives = 0;
Standard_Integer aNbLinkPrimitives = 0;
for (it.Reset(); it.More(); it.Next())
{
Standard_Integer aNbNodes = 0;
if (!aSource->GetGeom (it.Key(), Standard_True, aCoords, aNbNodes, aType))
continue;
if (aType == MeshVS_ET_Volume)
{
if (aSource->Get3DGeom (it.Key(), aNbNodes, aTopo))
{
for (Standard_Integer aFaceIdx = aTopo->Lower(); aFaceIdx <= aTopo->Upper(); ++aFaceIdx)
{
const TColStd_SequenceOfInteger& aFaceNodes = aTopo->Value (aFaceIdx);
aNbEdgePrimitives += aFaceNodes.Length(); // add edge segments
aNbVolmPrimitives += aFaceNodes.Length() - 2; // add volumetric cell triangles
}
}
}
else if (aType == MeshVS_ET_Link)
{
aNbLinkPrimitives += aNbNodes - 1; // add link segments
}
else if (aType == MeshVS_ET_Face)
{
aNbEdgePrimitives += aNbNodes; // add edge segments
aNbFacePrimitives += aNbNodes - 2; // add face triangles
}
}
// Here we do not use indices arrays because they are not effective for some mesh
// drawing modes: shrinking mode (displaces the vertices inside the polygon), 3D
// cell rendering (normal interpolation is not always applicable - flat shading),
// elemental coloring (color interpolation is impossible)
// Create array of polygons for interior presentation of faces and volumes
Handle(Graphic3d_ArrayOfTriangles) aFaceTriangles = new Graphic3d_ArrayOfTriangles
( (aNbFacePrimitives + aNbVolmPrimitives) * 3, 0, myUseTexture || IsReflect, !myUseTexture, myUseTexture );
// Create array of polylines for presentation of edges
// (used for optimization insted of SetEdgeOn method call)
Handle(Graphic3d_ArrayOfPolylines) aPolyL = new Graphic3d_ArrayOfPolylines
( ( aMaxFaceNodes + 1 ) * aSize + PolygonVerticesFor3D, aSize + PolygonBoundsFor3D );
Handle(Graphic3d_ArrayOfSegments) anEdgeSegments = new Graphic3d_ArrayOfSegments
(aNbEdgePrimitives * 2);
gp_Pnt P, Start;
Standard_Real aMin = gp::Resolution() * gp::Resolution();
@@ -238,10 +289,11 @@ void MeshVS_NodalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)& Prs,
for (it.Reset(); it.More(); it.Next())
{
Standard_Integer aKey = it.Key();
if (aSource->GetGeom (aKey, Standard_True, aCoords, NbNodes, aType))
{
MeshVS_Buffer aNodesBuf (NbNodes*sizeof(Standard_Integer));
TColStd_Array1OfInteger aNodes(aNodesBuf, 1, NbNodes);
TColStd_Array1OfInteger aNodes (1, NbNodes);
if (!aSource->GetNodesByElement (aKey, aNodes, NbNodes))
continue;
@@ -249,14 +301,15 @@ void MeshVS_NodalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)& Prs,
Standard_Boolean isValid = Standard_True;
Standard_Integer i;
if (myUseTexture)
{
for ( i = 1; i <= NbNodes && isValid; i++ )
for (i = 1; i <= NbNodes && isValid; ++i)
isValid = myTextureCoords.IsBound (aNodes (i));
}
else
{
for ( i = 1; i <= NbNodes && isValid; i++ )
for (i = 1; i <= NbNodes && isValid; ++i)
isValid = GetColor (aNodes (i), aNColor);
}
@@ -265,170 +318,96 @@ void MeshVS_NodalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)& Prs,
// Preparing normal(s) to show reflections if requested
Handle(TColStd_HArray1OfReal) aNormals;
Standard_Boolean hasNormals =
(IsReflect && aSource->GetNormalsByElement (aKey, IsMeshSmoothShading, aMaxFaceNodes, aNormals));
if (aType == MeshVS_ET_Face)
{
aCPolyArr->AddBound ( NbNodes );
aPolyL->AddBound ( NbNodes + 1 );
for ( i = 1; i <= NbNodes; i++)
for (Standard_Integer aNodeIdx = 0; aNodeIdx < NbNodes - 2; ++aNodeIdx) // triangulate polygon
{
P = gp_Pnt( aCoords( 3 * i - 2 ), aCoords( 3 * i - 1 ), aCoords( 3 * i ) );
if ( myUseTexture )
for (Standard_Integer aSubIdx = 0; aSubIdx < 3; ++aSubIdx) // generate sub-triangle
{
int anId = aNodes( i );
double aTexCoord = myTextureCoords( anId );
gp_XYZ aPnt (aCoords (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 1),
aCoords (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 2),
aCoords (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 3));
// transform texture coordinate in accordance with number of colors specified
// by upper level and real size of Gl texture
// The Gl texture has border colors interpolated with the colors from the color map,
// thats why we need to shrink texture coordinates around the middle point to
// exclude areas where the map colors are interpolated with the borders color
double aWrapCoord = 1.0 / (2.0 * nbTextureColors) + aTexCoord * (nbColors - 1.0) / nbTextureColors;
gp_Vec aNorm = aDefNorm;
if (hasNormals)
{
gp_Vec aNorm(aNormals->Value( 3 * i - 2 ),
aNormals->Value( 3 * i - 1 ),
aNormals->Value( 3 * i ));
// There are two "rows" of colors: user's invalid color at the top
// of texture and line of map colors at the bottom of the texture.
// Since the texture has borders, which are interpolated with the "rows" of colors
// we should specify the 0.25 offset to get the correct texture color
aNorm.SquareMagnitude() > aMin ?
aCPolyArr->AddVertex(P, gp_Dir( aNorm ),
gp_Pnt2d( aWrapCoord, aTexCoord >= 0 && aTexCoord <= 1 ? 0.75 : 0.25 ) ) :
aCPolyArr->AddVertex(P, aDefNorm,
gp_Pnt2d( aWrapCoord, aTexCoord >= 0 && aTexCoord <= 1 ? 0.75 : 0.25 ) );
gp_Vec aTestNorm (aNormals->Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 1),
aNormals->Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 2),
aNormals->Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 3));
if (aTestNorm.SquareMagnitude() > aMin)
{
aNorm = gp_Dir (aTestNorm);
}
else
aCPolyArr->AddVertex( P, aDefNorm,
gp_Pnt2d( aWrapCoord, aTexCoord >= 0 && aTexCoord <= 1 ? 0.75 : 0.25 ) );
}
if (myUseTexture)
{
const Standard_Real aTexCoord = myTextureCoords (aNodes (aSubIdx == 0 ? 1 : (aNodeIdx + aSubIdx + 1)));
// Transform texture coordinate in accordance with number of colors specified
// by upper level and real size of OpenGL texture. The OpenGL texture has border
// colors interpolated with the colors from the color map, thats why we need to
// shrink texture coordinates around the middle point to exclude areas where the
// map colors are interpolated with the borders color
aFaceTriangles->AddVertex (aPnt, aNorm, gp_Pnt2d (
(aTexCoord * (nbColors - 1.0) + 0.5) / nbTextureColors, aTexCoord < 0 || aTexCoord > 1 ? 0.25 : 0.75));
}
else
{
GetColor ( aNodes( i ), aNColor );
GetColor (aNodes (aSubIdx == 0 ? 1 : (aNodeIdx + aSubIdx + 1)), aNColor);
if (IsReflect)
{
// Simulating TelUpdateMaterial() from OpenGl_attri.c
// to get the same colors in elemental and nodal color prs builders
aNColor.SetValues (anColorRatio * aNColor.Red(),
anColorRatio * aNColor.Green(),
anColorRatio * aNColor.Blue(),
Quantity_TOC_RGB);
if ( hasNormals )
aFaceTriangles->AddVertex (aPnt, aNorm, aNColor);
}
else
{
gp_Vec aNorm(aNormals->Value( 3 * i - 2 ),
aNormals->Value( 3 * i - 1 ),
aNormals->Value( 3 * i ));
aNorm.SquareMagnitude() > aMin ?
aCPolyArr->AddVertex(P, gp_Dir( aNorm ), aNColor ) :
aCPolyArr->AddVertex(P, aDefNorm , aNColor );
aFaceTriangles->AddVertex (aPnt, aNColor);
}
else
aCPolyArr->AddVertex(P, aDefNorm, aNColor );
}
else
aCPolyArr->AddVertex( P, aNColor );
}
aPolyL->AddVertex ( P );
if ( i == 1 )
Start = P;
}
aPolyL->AddVertex ( Start );
for (Standard_Integer aNodeIdx = 0; aNodeIdx < NbNodes; ++aNodeIdx) // border segmentation
{
const Standard_Integer aNextIdx = (aNodeIdx + 1) % NbNodes;
anEdgeSegments->AddVertex (aCoords (3 * aNodeIdx + 1),
aCoords (3 * aNodeIdx + 2),
aCoords (3 * aNodeIdx + 3));
anEdgeSegments->AddVertex (aCoords (3 * aNextIdx + 1),
aCoords (3 * aNextIdx + 2),
aCoords (3 * aNextIdx + 3));
}
// if IsExcludingOn then presentation must not be built by other builders
if (IsExcludingOn())
{
IDsToExclude.Add (aKey);
}
}
else if (aType == MeshVS_ET_Volume)
{
if (!aSource->Get3DGeom (aKey, NbNodes, aTopo))
continue;
// iterate through faces of volume
for ( Standard_Integer k = aTopo->Lower(), last = aTopo->Upper(), normIndex = 1; k <= last; k++, normIndex++ )
{
const TColStd_SequenceOfInteger& aSeq = aTopo->Value( k );
Standard_Integer m = aSeq.Length(), ind;
AddVolumePrs (aTopo, aNodes, aCoords, aFaceTriangles,
IsReflect, nbColors, nbTextureColors, anColorRatio);
// build polygon & polylines for current face
aCPolyArr->AddBound( m );
aPolyL->AddBound( m + 1 );
for ( Standard_Integer j = 1; j <= m; j++ )
{
ind = aSeq.Value( j );
P = gp_Pnt( aCoords( 3 * ind + 1 ),
aCoords( 3 * ind + 2 ),
aCoords( 3 * ind + 3 ) );
if ( myUseTexture )
{
Standard_Integer anId = aNodes( ind + 1 );
Standard_Real aTexCoord = myTextureCoords( anId );
// transform texture coordinate in accordance with number of colors specified
// by upper level and real size of Gl texture
// The Gl texture has border colors interpolated with the colors from the color map,
// thats why we need to shrink texture coordinates around the middle point to
// exclude areas where the map colors are interpolated with the borders color
double aWrapCoord = 1.0 / (2.0 * nbTextureColors) + aTexCoord * (nbColors - 1.0) / nbTextureColors;
if ( hasNormals )
{
gp_Vec aNorm(aNormals->Value( 3 * i - 2 ),
aNormals->Value( 3 * i - 1 ),
aNormals->Value( 3 * i ));
// There are two "rows" of colors: user's invalid color at the top
// of texture and line of map colors at the bottom of the texture.
// Since the texture has borders, which are interpolated with the "rows" of colors
// we should specify the 0.25 offset to get the correct texture color
aNorm.SquareMagnitude() > aMin ?
aCPolyArr->AddVertex(P, gp_Dir( aNorm ),
gp_Pnt2d( aWrapCoord, aTexCoord >= 0 && aTexCoord <= 1 ? 0.75 : 0.25 ) ) :
aCPolyArr->AddVertex(P, aDefNorm,
gp_Pnt2d( aWrapCoord, aTexCoord >= 0 && aTexCoord <= 1 ? 0.75 : 0.25 ) );
}
else
aCPolyArr->AddVertex( P, aDefNorm,
gp_Pnt2d( aWrapCoord, aTexCoord >= 0 && aTexCoord <= 1 ? 0.75 : 0.25 ) );
}
else
{
GetColor( aNodes( ind + 1 ), aNColor );
if ( IsReflect )
{
// Simulating TelUpdateMaterial() from OpenGl_attri.c
// to get the same colors in elemental and nodal color prs builders
aNColor.SetValues(anColorRatio * aNColor.Red(),
anColorRatio * aNColor.Green(),
anColorRatio * aNColor.Blue(),
Quantity_TOC_RGB);
if ( hasNormals )
{
gp_Vec aNorm(aNormals->Value( 3 * normIndex - 2 ),
aNormals->Value( 3 * normIndex - 1 ),
aNormals->Value( 3 * normIndex ));
aNorm.SquareMagnitude() > aMin ?
aCPolyArr->AddVertex( P, gp_Dir( aNorm ), aNColor ) :
aCPolyArr->AddVertex( P, aDefNorm , aNColor );
}
else
aCPolyArr->AddVertex( P, aDefNorm, aNColor );
}
else
aCPolyArr->AddVertex( P, aNColor );
}
aPolyL->AddVertex ( P );
if ( j == 1 )
Start = P;
}
aPolyL->AddVertex ( Start );
}
AddVolumePrs (aTopo, aNodes, aCoords, anEdgeSegments,
IsReflect, nbColors, nbTextureColors, anColorRatio);
// if IsExcludingOn then presentation must not be built by other builders
if (IsExcludingOn())
@@ -500,7 +479,8 @@ void MeshVS_NodalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)& Prs,
Handle(Graphic3d_Group) aGroup1 = Prs3d_Root::CurrentGroup ( Prs );
aGroup1->SetPrimitivesAspect( anAsp );
aGroup1->AddPrimitiveArray( aCPolyArr );
aGroup1->AddPrimitiveArray( aFaceTriangles /*aCPolyArr*/ );
//aGroup1->AddPrimitiveArray( aCPolyArr );
if (aShowEdges)
{
@@ -511,11 +491,136 @@ void MeshVS_NodalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)& Prs,
anAsp->SetTextureMapOff();
aGroup2->SetPrimitivesAspect( anAsp );
aGroup2->SetPrimitivesAspect( anLAsp );
aGroup2->AddPrimitiveArray( aPolyL );
aGroup2->AddPrimitiveArray( anEdgeSegments );
anAsp->SetEdgeOn();
}
}
//================================================================
// Function : AddVolumePrs
// Purpose :
//================================================================
void MeshVS_NodalColorPrsBuilder::AddVolumePrs (const Handle(MeshVS_HArray1OfSequenceOfInteger)& theTopo,
const TColStd_Array1OfInteger& theNodes,
const TColStd_Array1OfReal& theCoords,
const Handle(Graphic3d_ArrayOfPrimitives)& theArray,
const Standard_Boolean theIsShaded,
const Standard_Integer theNbColors,
const Standard_Integer theNbTexColors,
const Standard_Real theColorRatio) const
{
Standard_Integer aLow = theCoords.Lower();
if (theTopo.IsNull() || theArray.IsNull())
return;
Standard_Boolean aIsPolygons = theArray->IsKind (STANDARD_TYPE (Graphic3d_ArrayOfTriangles));
if (aIsPolygons)
{
for (Standard_Integer aFaceIdx = theTopo->Lower(), topoup = theTopo->Upper(); aFaceIdx <= topoup; ++aFaceIdx)
{
const TColStd_SequenceOfInteger& aFaceNodes = theTopo->Value (aFaceIdx);
TColStd_Array1OfReal aPolyNodes (0, 3 * aFaceNodes.Length());
for (Standard_Integer aNodeIdx = 0; aNodeIdx < aFaceNodes.Length(); ++aNodeIdx)
{
Standard_Integer anIdx = aFaceNodes.Value (aNodeIdx + 1);
Standard_Real aX = theCoords.Value (aLow + 3 * anIdx + 0);
Standard_Real aY = theCoords.Value (aLow + 3 * anIdx + 1);
Standard_Real aZ = theCoords.Value (aLow + 3 * anIdx + 2);
aPolyNodes.SetValue (3 * aNodeIdx + 1, aX);
aPolyNodes.SetValue (3 * aNodeIdx + 2, aY);
aPolyNodes.SetValue (3 * aNodeIdx + 3, aZ);
}
gp_Vec aNorm (0.0, 0.0, 1.0);
if (theIsShaded)
{
aPolyNodes.SetValue (0, aFaceNodes.Length());
if (!MeshVS_Tool::GetAverageNormal (aPolyNodes, aNorm))
{
aNorm.SetCoord (0.0, 0.0, 1.0);
}
}
for (Standard_Integer aNodeIdx = 0; aNodeIdx < aFaceNodes.Length() - 2; ++aNodeIdx) // triangulate polygon
{
for (Standard_Integer aSubIdx = 0; aSubIdx < 3; ++aSubIdx) // generate sub-triangle
{
gp_Pnt aPnt (aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 1),
aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 2),
aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 3));
if (myUseTexture)
{
const Standard_Real aTexCoord = myTextureCoords (theNodes (aFaceNodes (aSubIdx == 0 ? 1 : (aNodeIdx + aSubIdx + 1)) + 1));
theArray->AddVertex (aPnt, aNorm, gp_Pnt2d (
(aTexCoord * (theNbColors - 1.0) + 0.5) / theNbTexColors, aTexCoord < 0 || aTexCoord > 1 ? 0.25 : 0.75));
}
else
{
Quantity_Color aNColor;
GetColor (theNodes ((aFaceNodes (aSubIdx == 0 ? 1 : (aNodeIdx + aSubIdx + 1)) + 1)), aNColor);
if (theIsShaded)
{
aNColor.SetValues (theColorRatio * aNColor.Red(),
theColorRatio * aNColor.Green(),
theColorRatio * aNColor.Blue(),
Quantity_TOC_RGB);
theArray->AddVertex (aPnt, aNorm, aNColor);
}
else
{
theArray->AddVertex (aPnt, aNColor);
}
}
}
}
}
}
else
{
// Find all pairs of nodes (edges) to draw (will be drawn only once)
NCollection_Map<MeshVS_NodePair, MeshVS_SymmetricPairHasher> aEdgeMap;
for (Standard_Integer aFaceIdx = theTopo->Lower(), topoup = theTopo->Upper(); aFaceIdx <= topoup; ++aFaceIdx)
{
const TColStd_SequenceOfInteger& aFaceNodes = theTopo->Value (aFaceIdx);
for (Standard_Integer aNodeIdx = 0, aNbNodes = aFaceNodes.Length(); aNodeIdx < aNbNodes; ++aNodeIdx)
{
const Standard_Integer aNextIdx = (aNodeIdx + 1) % aNbNodes;
aEdgeMap.Add (MeshVS_NodePair (aFaceNodes.Value (aNodeIdx + 1),
aFaceNodes.Value (aNextIdx + 1)));
}
}
// Draw edges
for(NCollection_Map<MeshVS_NodePair, MeshVS_SymmetricPairHasher>::Iterator anIt (aEdgeMap); anIt.More(); anIt.Next())
{
const Standard_Integer anIdx1 = aLow + 3 * anIt.Key().first;
const Standard_Integer anIdx2 = aLow + 3 * anIt.Key().second;
Standard_Real aX[] = { theCoords.Value (anIdx1 + 0), theCoords.Value (anIdx2 + 0) };
Standard_Real aY[] = { theCoords.Value (anIdx1 + 1), theCoords.Value (anIdx2 + 1) };
Standard_Real aZ[] = { theCoords.Value (anIdx1 + 2), theCoords.Value (anIdx2 + 2) };
theArray->AddVertex (aX[0], aY[0], aZ[0]);
theArray->AddVertex (aX[1], aY[1], aZ[1]);
}
}
}
//================================================================
// Function : SetColors
// Purpose :

View File

@@ -0,0 +1,23 @@
#ifndef _MeshVS_SymmetricPairHasher_HeaderFile
#define _MeshVS_SymmetricPairHasher_HeaderFile
#include <Standard_Type.hxx>
typedef std::pair<Standard_Integer, Standard_Integer> MeshVS_NodePair;
//! Provides symmetric hash methods pair of integers.
struct MeshVS_SymmetricPairHasher
{
static Standard_Integer HashCode (const MeshVS_NodePair& thePair, const Standard_Integer theMaxCode)
{
return ((thePair.first + thePair.second) & 0x7FFFFFFF) % theMaxCode + 1;
}
static Standard_Boolean IsEqual (const MeshVS_NodePair& thePair1, const MeshVS_NodePair& thePair2)
{
return (thePair1.first == thePair2.first && thePair1.second == thePair2.second)
|| (thePair1.first == thePair2.second && thePair1.second == thePair2.first);
}
};
#endif // _MeshVS_SymmetricPairHasher_HeaderFile

View File

@@ -19,6 +19,8 @@
#include <Graphic3d_ArrayOfPolylines.hxx>
#include <Graphic3d_ArrayOfPolygons.hxx>
#include <Graphic3d_ArrayOfSegments.hxx>
#include <Graphic3d_ArrayOfTriangles.hxx>
#include <Graphic3d_ArrayOfTriangleFans.hxx>
#include <Graphic3d_MaterialAspect.hxx>
#include <Graphic3d_AspectLine3d.hxx>
@@ -226,19 +228,12 @@ void MeshVS_VectorPrsBuilder::Build ( const Handle(Prs3d_Presentation)& Prs,
// polylines
Standard_Integer aNbVertices = aNbVectors * NB_VERTICES;
Standard_Integer aNbBounds = aNbVectors * NB_BOUNDS;
// fans
Standard_Integer aNbTriangleVertices = aNbVectors * (NB_TRIANGLES + 2);
Standard_Integer aNbFans = aNbVectors * NB_TRIANGLES;
Handle(Graphic3d_ArrayOfPrimitives) aLineArray = new Graphic3d_ArrayOfSegments (aNbVertices);
Handle(Graphic3d_ArrayOfPrimitives) aArrowLineArray = new Graphic3d_ArrayOfSegments (aNbVertices);
Handle(Graphic3d_ArrayOfPrimitives) aLineArray =
new Graphic3d_ArrayOfPolylines(aNbVertices, aNbBounds);
Handle(Graphic3d_ArrayOfPrimitives) aArrowLineArray =
new Graphic3d_ArrayOfPolylines(aNbVertices, aNbBounds);
Handle(Graphic3d_ArrayOfTriangleFans) aTriangleArray =
new Graphic3d_ArrayOfTriangleFans(aNbTriangleVertices, aNbFans);
Handle(Graphic3d_ArrayOfPrimitives) aTriangleArray = new Graphic3d_ArrayOfSegments (
aNbVectors * 8 /* vertices per arrow */, aNbVectors * 12 /* segments per arrow */ * 2 /* indices per segment */);
TColgp_Array1OfPnt anArrowPnt(1,8);
Standard_Real k, b, aMaxValue, aMinValue, aValue, X, Y, Z;
@@ -261,7 +256,7 @@ void MeshVS_VectorPrsBuilder::Build ( const Handle(Prs3d_Presentation)& Prs,
TColStd_PackedMapOfInteger aCustomElements;
// subtract the hidden elements and ids to exclude (to minimise allocated memory)
// subtract the hidden elements and ids to exclude (to minimize allocated memory)
TColStd_PackedMapOfInteger anIDs;
anIDs.Assign( IDs );
if ( IsElement )
@@ -338,17 +333,10 @@ void MeshVS_VectorPrsBuilder::Build ( const Handle(Prs3d_Presentation)& Prs,
if ( !myIsSimplePrs )
{
Graphic3d_MaterialAspect aMatAspect;
aMatAspect.SetAmbient( 1 );
aMatAspect.SetDiffuse( 0 );
aMatAspect.SetEmissive( 0 );
aMatAspect.SetShininess( 1 );
aMatAspect.SetSpecular( 0 );
Handle(Graphic3d_AspectFillArea3d) aFillAspect =
new Graphic3d_AspectFillArea3d (Aspect_IS_HOLLOW, aColor, aColor, Aspect_TOL_SOLID,
1., aMatAspect, aMatAspect );
Handle(Graphic3d_AspectLine3d) anArrowLinAspect =
new Graphic3d_AspectLine3d (aColor, Aspect_TOL_SOLID, mySimpleWidthPrm);
aVGroup->SetPrimitivesAspect( aFillAspect );
aVGroup->SetPrimitivesAspect( anArrowLinAspect );
aVGroup->AddPrimitiveArray( aTriangleArray );
}
else
@@ -369,58 +357,68 @@ void MeshVS_VectorPrsBuilder::Build ( const Handle(Prs3d_Presentation)& Prs,
// Purpose : Fill arrays of primitives for drawing force
//=======================================================================
void MeshVS_VectorPrsBuilder::DrawVector ( const gp_Trsf& theTrsf,
const Standard_Real Length,
const Standard_Real MaxLength,
const TColgp_Array1OfPnt& ArrowPoints,
const Handle(Graphic3d_ArrayOfPrimitives)& Lines,
const Handle(Graphic3d_ArrayOfPrimitives)& ArrowLines,
const Handle(Graphic3d_ArrayOfPrimitives)& Triangles) const
const Standard_Real theLength,
const Standard_Real theMaxLength,
const TColgp_Array1OfPnt& theArrowPoints,
const Handle(Graphic3d_ArrayOfPrimitives)& theLines,
const Handle(Graphic3d_ArrayOfPrimitives)& theArrowLines,
const Handle(Graphic3d_ArrayOfPrimitives)& theTriangles) const
{
const int PntNum = 8;
const Standard_Real aMinLength = MaxLength * ( 1 - mySimpleStartPrm );
const Standard_Real aLocalLength = ( !myIsSimplePrs || Length > aMinLength ? Length : aMinLength );
const Standard_Real aMinLength = theMaxLength * ( 1 - mySimpleStartPrm );
const Standard_Real aLocalLength = ( !myIsSimplePrs || theLength > aMinLength ? theLength : aMinLength );
// draw line
gp_Pnt aLinePnt[ 2 ] = { gp_Pnt( 0, 0, 0 ) , gp_Pnt( 0, 0, aLocalLength ) };
theTrsf.Transforms (aLinePnt[0].ChangeCoord());
theTrsf.Transforms (aLinePnt[1].ChangeCoord());
Lines->AddBound( 2 );
Lines->AddVertex( aLinePnt[ 0 ] );
Lines->AddVertex( aLinePnt[ 1 ] );
theLines->AddVertex (aLinePnt[0]);
theLines->AddVertex (aLinePnt[1]);
// draw arrow
if (!myIsSimplePrs)
{
Standard_Integer l = ArrowPoints.Lower(),
u = ArrowPoints.Upper(),
i;
if ( u-l < PntNum-1 )
Standard_Integer aLower = theArrowPoints.Lower(),
aUpper = theArrowPoints.Upper();
if (aUpper - aLower < PntNum - 1)
return;
TColgp_Array1OfPnt anArrowPnt( l, u );
for ( i = l; i < l+PntNum; i++ )
TColgp_Array1OfPnt anArrowPnt (aLower, aUpper);
for (Standard_Integer aPntIdx = aLower; aPntIdx < aLower + PntNum; ++aPntIdx)
{
anArrowPnt( i ).ChangeCoord() = ArrowPoints ( i ).Coord() + gp_XYZ( 0, 0, aLocalLength );
theTrsf.Transforms( anArrowPnt( i ).ChangeCoord() );
anArrowPnt (aPntIdx).ChangeCoord() = theArrowPoints (aPntIdx).Coord() + gp_XYZ (0, 0, aLocalLength);
theTrsf.Transforms (anArrowPnt (aPntIdx).ChangeCoord());
}
Triangles->AddBound(8);
for ( i = 0; i < PntNum; i++ )
Triangles->AddVertex( anArrowPnt( l+i ) );
const Standard_Integer aVrtOffset = theTriangles->VertexNumber() + 1;
for (Standard_Integer aPntIdx = 0; aPntIdx < PntNum; ++aPntIdx)
{
theTriangles->AddVertex (anArrowPnt (aLower + aPntIdx));
}
for (Standard_Integer aPntIdx = 1; aPntIdx <= PntNum - 2; ++aPntIdx)
{
theTriangles->AddEdge (aVrtOffset);
theTriangles->AddEdge (aVrtOffset + aPntIdx);
theTriangles->AddEdge (aVrtOffset + aPntIdx);
theTriangles->AddEdge (aVrtOffset + aPntIdx + 1);
}
}
else
{
const Standard_Real aEndPos = aLocalLength - MaxLength * ( 1 - mySimpleEndPrm );
const Standard_Real aArrowLength = MaxLength * ( mySimpleEndPrm - mySimpleStartPrm );
const Standard_Real aEndPos = aLocalLength - theMaxLength * ( 1 - mySimpleEndPrm );
const Standard_Real aArrowLength = theMaxLength * ( mySimpleEndPrm - mySimpleStartPrm );
gp_Pnt aArrowPnt[ 2 ] = { gp_Pnt( 0, 0, aEndPos - aArrowLength ),
gp_Pnt( 0, 0, aEndPos ) };
theTrsf.Transforms (aArrowPnt[0].ChangeCoord());
theTrsf.Transforms (aArrowPnt[1].ChangeCoord());
ArrowLines->AddBound( 2 );
ArrowLines->AddVertex( aArrowPnt[ 0 ] );
ArrowLines->AddVertex( aArrowPnt[ 1 ] );
theArrowLines->AddVertex (aArrowPnt[0]);
theArrowLines->AddVertex (aArrowPnt[1]);
}
}