1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +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,129 +258,227 @@ 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() );
if (anEdgeOn)
anAsp->SetEdgeOn();
else
anAsp->SetEdgeOff();
Handle(Graphic3d_AspectLine3d) anEdgeAspect =
new Graphic3d_AspectLine3d ( anEdgeColor, anEdgeType, anEdgeWidth );
for( it.Reset(); it.More(); it.Next() )
aFillAspect->SetDistinguishOff ();
aFillAspect->SetInteriorColor ( aColIter.Key() );
if (anEdgeOn)
aFillAspect->SetEdgeOn();
else
aFillAspect->SetEdgeOff();
for (it.Reset(); it.More(); it.Next())
{
Standard_Integer aKey = it.Key();
if( aColIter.Value().Contains( aKey ) )
if (aColIter.Value().Contains (aKey))
{
if ( !aSource->GetGeom ( aKey, Standard_True, aCoords, NbNodes, aType ) )
if (!aSource->GetGeom (aKey, Standard_True, aCoords, NbNodes, aType))
continue;
if( aType == MeshVS_ET_Face )
if (aType != MeshVS_ET_Face && aType != MeshVS_ET_Link && aType != MeshVS_ET_Volume)
{
aPolyGArr->AddBound ( NbNodes );
if( IsExcludingOn() )
IDsToExclude.Add( aKey );
aCustomElements.Add (aKey);
continue;
}
else if( aType == MeshVS_ET_Link )
if (IsExcludingOn())
IDsToExclude.Add (aKey);
if (aType == MeshVS_ET_Volume)
{
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 ) )
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
{
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 );
// Adding vertices (with normals if necessary)
for ( i=1; i<=NbNodes; i++ )
if ( aType == MeshVS_ET_Face )
{
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. );
}
else
aPolyGArr->AddVertex ( aCoords(3 * i - 2),
aCoords(3 * i - 1),
aCoords(3 * i ) );
IsPolyG = Standard_True;
}
else if ( aType == MeshVS_ET_Link )
MeshVS_MeshPrsBuilder::AddVolumePrs (aTopo, aCoords,
NbNodes, aFaceTriangles, IsReflect, Standard_False, Standard_False, 1.0);
if (anEdgeOn)
{
aPolyLArr->AddVertex ( aCoords(3*i-2), aCoords(3*i-1), aCoords(3*i) );
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)
{
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
{
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)
{
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 )
if (IsPolyG)
{
aGGroup->SetPrimitivesAspect ( anAsp );
aGGroup->AddPrimitiveArray ( aPolyGArr );
}
if ( IsPolyL )
{
anAsp->SetEdgeOff();
aLGroup->SetPrimitivesAspect ( anAsp );
aLGroup->SetPrimitivesAspect ( anLAsp );
aLGroup->AddPrimitiveArray ( aPolyLArr );
aFillAspect->SetEdgeOff();
aGGroup->SetPrimitivesAspect (aFillAspect);
aGGroup->AddPrimitiveArray (aFaceTriangles);
if (anEdgeOn)
anAsp->SetEdgeOn();
{
aFillAspect->SetEdgeOff();
aSGroup->AddPrimitiveArray (anEdgeSegments);
aSGroup->SetGroupPrimitivesAspect (anEdgeAspect);
}
}
if (IsPolyL)
{
aFillAspect->SetEdgeOff();
aLGroup->SetPrimitivesAspect (aFillAspect);
aLGroup->SetPrimitivesAspect (aLinkAspect);
aLGroup->AddPrimitiveArray (aLinkSegments);
if (anEdgeOn)
aFillAspect->SetEdgeOn();
else
anAsp->SetEdgeOff();
aFillAspect->SetEdgeOff();
}
if( !aCustomElements.IsEmpty() )
CustomBuild( Prs, aCustomElements, IDsToExclude, DisplayMode );
if (!aCustomElements.IsEmpty())
CustomBuild(Prs, aCustomElements, IDsToExclude, DisplayMode);
}
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() )
{
@@ -460,43 +589,60 @@ void MeshVS_ElementalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)&
if( IsExcludingOn() )
IDsToExclude.Add( aKey );
if ( aType == MeshVS_ET_Face && NbNodes > 0 )
if (aType == MeshVS_ET_Face && NbNodes > 0)
{
// Preparing normal(s) to show reflections if requested
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 &&*/
aSource->GetNormalsByElement( aKey, IsMeshSmoothShading, aMaxFaceNodes, aNormals );
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)
{
if ( IsReflect )
for (Standard_Integer anIdx = 0; anIdx < 3; ++anIdx)
{
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. );
if (IsReflect)
{
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
{
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));
}
else
aPolyArr->AddVertex ( aCoords(3*i-2),
aCoords(3*i-1),
aCoords(3*i ) );
}
}
}
}
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
AddFaceSolidPrs ( me; ID : Integer;
theCoords : Array1OfReal from TColStd;
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;

File diff suppressed because it is too large Load Diff

View File

@@ -35,17 +35,21 @@ uses
Boolean from Standard,
Integer from Standard,
DisplayModeFlags from MeshVS,
Mesh from MeshVS,
MeshPtr from MeshVS,
DataSource from MeshVS,
DataMapOfIntegerColor from MeshVS,
BuilderPriority from MeshVS,
SequenceOfColor from Aspect,
Color from Quantity,
DataMapOfIntegerReal from TColStd,
Texture2D from Graphic3d,
PackedMapOfInteger from TColStd
DisplayModeFlags from MeshVS,
Mesh from MeshVS,
MeshPtr from MeshVS,
DataSource from MeshVS,
DataMapOfIntegerColor from MeshVS,
BuilderPriority from MeshVS,
HArray1OfSequenceOfInteger from MeshVS,
SequenceOfColor from Aspect,
Color from Quantity,
Texture2D from Graphic3d,
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();
@@ -235,204 +286,132 @@ void MeshVS_NodalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)& Prs,
// Prepare for scaling the incoming colors
Standard_Real anColorRatio = aMaterial[0].Ambient();
for( it.Reset(); it.More(); it.Next() )
for (it.Reset(); it.More(); it.Next())
{
Standard_Integer aKey = it.Key();
if ( aSource->GetGeom ( aKey, Standard_True, aCoords, NbNodes, aType ) )
if (aSource->GetGeom (aKey, Standard_True, aCoords, NbNodes, aType))
{
MeshVS_Buffer aNodesBuf (NbNodes*sizeof(Standard_Integer));
TColStd_Array1OfInteger aNodes(aNodesBuf, 1, NbNodes);
if ( !aSource->GetNodesByElement ( aKey, aNodes, NbNodes ) )
TColStd_Array1OfInteger aNodes (1, NbNodes);
if (!aSource->GetNodesByElement (aKey, aNodes, NbNodes))
continue;
Quantity_Color aNColor;
Standard_Boolean isValid = Standard_True;
Standard_Integer i;
if ( myUseTexture )
if (myUseTexture)
{
for ( i = 1; i <= NbNodes && isValid; i++ )
isValid = myTextureCoords.IsBound( aNodes( i ) );
for (i = 1; i <= NbNodes && isValid; ++i)
isValid = myTextureCoords.IsBound (aNodes (i));
}
else
{
for ( i = 1; i <= NbNodes && isValid; i++ )
isValid = GetColor ( aNodes( i ), aNColor );
for (i = 1; i <= NbNodes && isValid; ++i)
isValid = GetColor (aNodes (i), aNColor);
}
if ( !isValid )
if (!isValid)
continue;
// Preparing normal(s) to show reflections if requested
Handle(TColStd_HArray1OfReal) aNormals;
Standard_Boolean hasNormals =
( IsReflect && aSource->GetNormalsByElement( aKey, IsMeshSmoothShading, aMaxFaceNodes, aNormals ) );
(IsReflect && aSource->GetNormalsByElement (aKey, IsMeshSmoothShading, aMaxFaceNodes, aNormals));
if ( aType == MeshVS_ET_Face )
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 )
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);
}
}
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
aCPolyArr->AddVertex( P, aDefNorm,
gp_Pnt2d( aWrapCoord, aTexCoord >= 0 && aTexCoord <= 1 ? 0.75 : 0.25 ) );
}
else
{
GetColor ( aNodes( i ), 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 )
GetColor (aNodes (aSubIdx == 0 ? 1 : (aNodeIdx + aSubIdx + 1)), aNColor);
if (IsReflect)
{
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 );
aNColor.SetValues (anColorRatio * aNColor.Red(),
anColorRatio * aNColor.Green(),
anColorRatio * aNColor.Blue(),
Quantity_TOC_RGB);
aFaceTriangles->AddVertex (aPnt, aNorm, aNColor);
}
else
aCPolyArr->AddVertex(P, aDefNorm, aNColor );
{
aFaceTriangles->AddVertex (aPnt, 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 );
if (IsExcludingOn())
{
IDsToExclude.Add (aKey);
}
}
else if ( aType == MeshVS_ET_Volume )
else if (aType == MeshVS_ET_Volume)
{
if ( !aSource->Get3DGeom( aKey, NbNodes, aTopo ) )
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;
// 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, aFaceTriangles,
IsReflect, nbColors, nbTextureColors, anColorRatio);
AddVolumePrs (aTopo, aNodes, aCoords, anEdgeSegments,
IsReflect, nbColors, nbTextureColors, anColorRatio);
// if IsExcludingOn then presentation must not be built by other builders
if ( IsExcludingOn() )
IDsToExclude.Add( aKey );
if (IsExcludingOn())
IDsToExclude.Add (aKey);
}
}
} // for ( ...
@@ -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>
@@ -225,20 +227,13 @@ void MeshVS_VectorPrsBuilder::Build ( const Handle(Prs3d_Presentation)& Prs,
return;
// polylines
Standard_Integer aNbVertices = aNbVectors * NB_VERTICES;
Standard_Integer aNbBounds = aNbVectors * NB_BOUNDS;
Standard_Integer aNbVertices = aNbVectors * NB_VERTICES;
// 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() );
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 )
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() );
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]);
}
}