Remove redundant code.
Fix GCC compilation warnings.
Bug fix in MeshVS_ElementalColorPrsBuilder.
MeshVS_TwoColors.cxx
MeshVS_TwoNodes.hxx
MeshVS_SelectionModeFlags.hxx
+MeshVS_SymmetricPairHasher.hxx
#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>
#include <MeshVS_DataMapIteratorOfDataMapOfColorMapOfInteger.hxx>
#include <MeshVS_MeshPrsBuilder.hxx>
#include <MeshVS_Buffer.hxx>
-
+#include <MeshVS_HArray1OfSequenceOfInteger.hxx>
//================================================================
// Function : Constructor MeshVS_ElementalColorPrsBuilder
}
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
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 );
+
+ 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);
- Handle (Graphic3d_ArrayOfPolygons) aPolyGArr = new Graphic3d_ArrayOfPolygons
- ( aMaxFaceNodes*aSize + PolygonVerticesFor3D, aSize + PolygonBoundsFor3D, 0, IsReflect );
+ 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() )
+ 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 )
- {
- aPolyGArr->AddBound ( NbNodes );
- if( IsExcludingOn() )
- IDsToExclude.Add( aKey );
- }
- else if( aType == MeshVS_ET_Link )
+
+ if (aType != MeshVS_ET_Face && aType != MeshVS_ET_Link && aType != MeshVS_ET_Volume)
{
- aPolyLArr->AddBound ( NbNodes );
- if( IsExcludingOn() )
- IDsToExclude.Add( aKey );
+ aCustomElements.Add (aKey);
+ continue;
}
- else if( aType == MeshVS_ET_Volume )
+
+ if (IsExcludingOn())
+ IDsToExclude.Add (aKey);
+
+ 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;
+ }
+
+ 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
+ else if (aType == MeshVS_ET_Face)
{
- aCustomElements.Add( aKey );
- continue;
- }
+ // Preparing normals
+ Handle(TColStd_HArray1OfReal) aNormals;
+ Standard_Boolean aHasNormals = IsReflect && aSource->GetNormalsByElement (aKey, IsMeshSmoothShading, aMaxFaceNodes, aNormals);
- // Preparing normal(s) to show reflections if requested
- Handle(TColStd_HArray1OfReal) aNormals;
- Standard_Boolean hasNormals = 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));
+ }
+ }
+ }
- // Adding vertices (with normals if necessary)
- for ( i=1; i<=NbNodes; i++ )
- if ( aType == MeshVS_ET_Face )
+ if (anEdgeOn)
{
- if ( IsReflect )
+ for (Standard_Integer aNodeIdx = 0; aNodeIdx < NbNodes; ++aNodeIdx)
{
- 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. );
+ 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
- aPolyGArr->AddVertex ( aCoords(3 * i - 2),
- aCoords(3 * i - 1),
- aCoords(3 * i ) );
- IsPolyG = Standard_True;
}
- else if ( aType == MeshVS_ET_Link )
+
+ IsPolyG = Standard_True;
+ }
+ else if (aType == MeshVS_ET_Link)
+ {
+ for (Standard_Integer aNodeIdx = 0; aNodeIdx < NbNodes - 1; ++aNodeIdx)
{
- aPolyLArr->AddVertex ( aCoords(3*i-2), aCoords(3*i-1), aCoords(3*i) );
+ 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 );
+ aFillAspect->SetEdgeOff();
+ aGGroup->SetPrimitivesAspect (aFillAspect);
+ aGGroup->AddPrimitiveArray (aFaceTriangles);
+
+ if (anEdgeOn)
+ {
+ aFillAspect->SetEdgeOff();
+ aSGroup->AddPrimitiveArray (anEdgeSegments);
+ aSGroup->SetGroupPrimitivesAspect (anEdgeAspect);
+ }
}
- if ( IsPolyL )
+ 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() )
- 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
{
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;
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() )
{
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 (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));
+ }
+ }
+ }
- for ( i=1; i<=NbNodes; i++ )
+ if (anEdgeOn)
{
- if ( IsReflect )
+ for (Standard_Integer aNodeIdx = 0; aNodeIdx < NbNodes; ++aNodeIdx)
{
- 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. );
+ 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);
}
}
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
---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
-
- AddFaceSolidPrs ( me; ID : Integer;
- theCoords : Array1OfReal from TColStd;
- NbNodes : Integer;
- MaxNodes : Integer;
- thePolygons : ArrayOfPolygons from Graphic3d;
- IsReflected : Boolean;
- IsShrinked : Boolean;
- ShrinkCoef : Real;
- IsMeshSmoothShading : Boolean
+ ---Purpose: Add to array of segments representing face's wire
+
+ 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
---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;
#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>
#include <TColStd_SequenceOfInteger.hxx>
#include <TColStd_PackedMapOfInteger.hxx>
#include <TColStd_HPackedMapOfInteger.hxx>
+#include <TColStd_MapOfInteger.hxx>
#include <Quantity_NameOfColor.hxx>
#include <Aspect_InteriorStyle.hxx>
#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
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() );
TColStd_PackedMapOfInteger& IDsToExclude,
const Standard_Integer DisplayMode ) const
{
- Standard_Integer maxnodes;
+ Standard_Integer maxnodes;
- Handle (MeshVS_DataSource) aSource = GetDataSource();
+ Handle(MeshVS_DataSource) aSource = GetDataSource();
if ( aSource.IsNull() )
return;
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 );
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();
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)
+ aNbVolmPrimitives += aFaceNodes.Length() - 2;
+ }
+ }
+ }
+ }
+ else if (aType == MeshVS_ET_Link)
+ {
+ if (showEdges)
+ {
+ aNbLinkPrimitives += 1; // add link segment
+ }
+ }
+ else if (aType == MeshVS_ET_Face)
{
- if( !HasSelectFlag )
- HowManyPrimitives( aTopo, Standard_True, HasSelectFlag, NbNodes,
- PolygonVerticesFor3D, PolygonBoundsFor3D );
- HowManyPrimitives( aTopo, Standard_False, HasSelectFlag, NbNodes,
- PolylineVerticesFor3D, PolylineBoundsFor3D );
+ 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 )
- {
- aPolygons = new Graphic3d_ArrayOfPolygons
- ( maxnodes*Extent, Extent, 0, Standard_True );
- aVolumes = new Graphic3d_ArrayOfPolygons
- ( PolygonVerticesFor3D, PolygonBoundsFor3D, 0, Standard_True );
- }
- else
+ Handle (Graphic3d_ArrayOfSegments) aLinkSegments;
+ Handle (Graphic3d_ArrayOfSegments) aEdgeSegments;
+
+ if (showEdges)
{
- 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 );
+ aFill->Values (anIntType, anIntColor, anEdgeColor, aLine, aWidth);
MeshVS_MapOfTwoNodes aLinkNodes;
- if ( showEdges && IsOverlapControl )
- // Forbid drawings of edges, which overlap with some links
- for( it.Reset(); it.More(); it.Next() )
+
+ // Forbid drawings of edges which overlap with some links
+ if (showEdges && IsOverlapControl)
+ {
+ 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() )
+ for (it.Reset(); it.More(); it.Next())
{
- Standard_Integer aKey = it.Key();
+ const Standard_Integer aKey = it.Key();
- if ( ! aSource->GetGeom ( aKey, Standard_True, aCoords, NbNodes, aType ) )
+ Standard_Integer NbNodes;
+ if (!aSource->GetGeom (aKey, Standard_True, aCoords, NbNodes, aType))
continue;
- switch ( aType )
+ if (!aSource->GetNodesByElement (aKey, aNodes, NbNodes))
+ continue;
+
+ switch (aType)
{
- case MeshVS_ET_Volume :
- if( IsExcludingOn() )
+ case MeshVS_ET_Volume:
+ {
+ if (IsExcludingOn())
IDsToExclude.Add (aKey);
- if( aSource->Get3DGeom( aKey, NbNodes, aTopo ) )
+
+ if (aSource->Get3DGeom (aKey, NbNodes, aTopo))
{
- // !!! TO DO: Overlap control
- // add wireframe presentation (draw edges for shading mode as well)
- if ( showEdges )
- AddVolumePrs ( aTopo, aCoords, NbNodes, aPolylines, IsReflect, IsShrink, HasSelectFlag, aShrinkCoef );
-
- // add shading presentation
- if ( ( IsShading || IsShrink ) && !HasSelectFlag )
- AddVolumePrs ( aTopo, aCoords, NbNodes, aVolumes, IsReflect, IsShrink, HasSelectFlag, aShrinkCoef );
+ // Add wire-frame presentation (draw edges for shading mode as well)
+ if (showEdges)
+ {
+ AddVolumePrs (aTopo, aCoords, NbNodes,
+ aEdgeSegments, IsReflect, IsShrink, HasSelectFlag, aShrinkCoef);
+ }
+
+ // Add shading presentation
+ if ((IsShading || IsShrink) && !HasSelectFlag)
+ {
+ AddVolumePrs (aTopo, aCoords, NbNodes,
+ aVolmTriangles, IsReflect, IsShrink, HasSelectFlag, aShrinkCoef);
+ }
}
- break;
+ }
+ break;
- case MeshVS_ET_Link :
- if( IsExcludingOn() )
+ case MeshVS_ET_Link:
+ {
+ if (IsExcludingOn())
IDsToExclude.Add (aKey);
- if ( showEdges )
- AddLinkPrs ( aCoords, aLinkPolylines, IsShrink || HasSelectFlag, aShrinkCoef );
- break;
- case MeshVS_ET_Face :
- if( IsExcludingOn() )
- IDsToExclude.Add (aKey);
- if ( showEdges && IsOverlapControl )
+ if (showEdges)
{
- MeshVS_Buffer aNodesBuf (NbNodes * sizeof(Standard_Integer));
- TColStd_Array1OfInteger aNodes (aNodesBuf, 1, NbNodes);
- if ( !aSource->GetNodesByElement( aKey, aNodes, NbNodes ) )
- continue;
+ AddLinkPrs (aCoords, aLinkSegments, IsShrink || HasSelectFlag, aShrinkCoef);
+ }
+ }
+ break;
+ case MeshVS_ET_Face:
+ {
+ if (IsExcludingOn())
+ IDsToExclude.Add (aKey);
+
+ if (showEdges && IsOverlapControl)
+ {
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) );
- if ( aLinkNodes.Contains ( aTwoNodes ) )
+ aTwoNodes.Second = (i < NbNodes) ? aNodes (i+1) : aNodes (1);
+
+ if (aLinkNodes.Contains (aTwoNodes))
+ {
+ for (Standard_Integer aNodeIdx = Last + 1; aNodeIdx < i; ++aNodeIdx)
{
- 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) );
- Last = i;
+ 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 )
+
+ 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;
+
+ 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));
- aPolylines->AddVertex ( aCoords(1), aCoords(2), aCoords(3) );
+ aSegmentMap.Add (aSegment);
+ }
+ }
}
}
- if ( !IsOverlapControl || IsShading )
+ if (!IsOverlapControl || IsShading)
{
- if ( !IsOverlapControl && showEdges )
- AddFaceWirePrs(aCoords, NbNodes, aPolylines,
- IsShrink || HasSelectFlag, aShrinkCoef );
- if ( ( IsShading || IsShrink ) && !HasSelectFlag )
- AddFaceSolidPrs(aKey, aCoords, NbNodes, maxnodes, aPolygons,
- IsReflect, IsShrink || HasSelectFlag,
- aShrinkCoef, IsMeshSmoothShading );
+ if (!IsOverlapControl && showEdges)
+ {
+ AddFaceWirePrs (aCoords, NbNodes,
+ aEdgeSegments, IsShrink || HasSelectFlag, aShrinkCoef);
+ }
+
+ if ((IsShading || IsShrink) && !HasSelectFlag)
+ {
+ AddFaceSolidPrs (aKey, aCoords, NbNodes, maxnodes, aFaceTriangles, IsReflect,
+ IsShrink || HasSelectFlag, aShrinkCoef, IsMeshSmoothShading);
+ }
}
- break;
+ }
+ break;
default:
- aCustomElements.Add( aKey );
- break;
+ {
+ aCustomElements.Add (aKey);
+ }
}
}
- if ( IsShrink )
+ if (IsShrink)
{
anOldEdgeColor = anEdgeColor;
- aFill->SetEdgeColor ( Quantity_NOC_BLACK );
+ 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() )
// Function : AddLinkPrs
// Purpose :
//================================================================
-void MeshVS_MeshPrsBuilder::AddLinkPrs (const TColStd_Array1OfReal& theCoords,
- const Handle(Graphic3d_ArrayOfPolylines)& theLines,
- const Standard_Boolean IsShrinked,
- const Standard_Real ShrinkCoef) const
+void MeshVS_MeshPrsBuilder::AddLinkPrs (const TColStd_Array1OfReal& theCoords,
+ 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;
-
- if ( IsShrinked )
+ 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 (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);
}
//================================================================
// Function : AddFaceWirePrs
// 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
+void MeshVS_MeshPrsBuilder::AddFaceWirePrs (const TColStd_Array1OfReal& theCoords,
+ 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 )
- {
- X = (X - xG) * ShrinkCoef + xG;
- Y = (Y - yG) * ShrinkCoef + yG;
- Z = (Z - zG) * ShrinkCoef + zG;
- }
- if( k==1 )
+ CalculateCenter (theCoords, theNbNodes, aCenterX, aCenterY, aCenterZ);
+ }
+
+ NCollection_Vector<gp_XYZ> aNodes (theNbNodes);
+
+ 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)
{
- 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,
- 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
+void MeshVS_MeshPrsBuilder::AddFaceSolidPrs (const Standard_Integer theID,
+ const TColStd_Array1OfReal& theCoords,
+ 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 (theIsShrinked)
+ {
+ CalculateCenter (theCoords, theNbNodes, aCenterX, aCenterY, aCenterZ);
+ }
- if( IsReflected )
+ NCollection_Vector<gp_XYZ> aVertexNormals (theMaxNodes);
+
+ if (theIsShaded)
{
- 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 );
+ if (theIsSmoothShading)
+ {
+ 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 (!theIsSmoothShading || aVertexNormals.Size() != theNbNodes)
+ {
+ aDataSource->GetNormal (theID, theMaxNodes, aNormalX, aNormalY, aNormalZ);
+ }
}
- for ( k=1; k<=NbNodes; k++)
+ NCollection_Vector<gp_XYZ> aNodes (theMaxNodes);
+
+ for (Standard_Integer aNodeIdx = 0; aNodeIdx < theNbNodes; ++aNodeIdx)
{
- X = theCoords(3*k-2);
- Y = theCoords(3*k-1);
- Z = theCoords(3*k);
- if ( IsShrinked )
+ gp_XYZ aPnt (theCoords (3 * aNodeIdx + 1),
+ theCoords (3 * aNodeIdx + 2),
+ theCoords (3 * aNodeIdx + 3));
+
+ if (theIsShrinked)
{
- X = (X - xG) * ShrinkCoef + xG;
- Y = (Y - yG) * ShrinkCoef + yG;
- Z = (Z - zG) * ShrinkCoef + zG;
+ aPnt.SetX ((aPnt.X() - aCenterX) * theShrinkingCoef + aCenterX);
+ aPnt.SetY ((aPnt.Y() - aCenterY) * theShrinkingCoef + aCenterY);
+ aPnt.SetZ ((aPnt.Z() - aCenterZ) * theShrinkingCoef + aCenterZ);
}
- if ( IsReflected )
+ aNodes.Append (aPnt);
+ }
+
+ // Triangulate polygon
+ for (Standard_Integer aNodeIdx = 0; aNodeIdx < theNbNodes - 2; ++aNodeIdx)
+ {
+ for (Standard_Integer aSubIdx = 0; aSubIdx < 3; ++aSubIdx)
{
- if( IsMeshSmoothShading && allNormals )
- aDS->GetNodeNormal (k, ID, nx, ny, nz);
- thePolygons->AddVertex ( X, Y, Z, nx, ny, nz );
+ 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
+ {
+ 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());
+ }
}
- else
- thePolygons->AddVertex ( X, Y, Z );
}
}
// 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 );
+ for (Standard_Integer aNodeIdx = 0; aNodeIdx < 3 * theNbNodes; ++aNodeIdx)
+ {
+ aCenter[aNodeIdx % 3] += theNodes.Value (aLow + aNodeIdx);
+ }
- c[0] /= n;
- c[1] /= n;
- c[2] /= n;
+ aCenter[0] /= theNbNodes;
+ aCenter[1] /= theNbNodes;
+ aCenter[2] /= theNbNodes;
}
- Standard_Boolean IsPolygons = Array->IsKind( STANDARD_TYPE( Graphic3d_ArrayOfPolygons ) );
- Standard_Real x[2], y[2], z[2];
- Standard_Integer ind;
- gp_Vec norm;
+ Standard_Boolean aIsPolygons = theArray->IsKind (STANDARD_TYPE (Graphic3d_ArrayOfTriangles));
- if( IsPolygons )
- {
- for( Standard_Integer i=Topo->Lower(), topoup=Topo->Upper(); i<=topoup; i++ )
+ if (aIsPolygons)
+ {
+ for (Standard_Integer aFaceIdx = theTopo->Lower(), topoup = theTopo->Upper(); aFaceIdx <= topoup; ++aFaceIdx)
{
- const TColStd_SequenceOfInteger& aSeq = Topo->Value( i );
-
- Standard_Integer m = aSeq.Length();
- Array->AddBound( m );
+ const TColStd_SequenceOfInteger& aFaceNodes = theTopo->Value (aFaceIdx);
+ const Standard_Integer aNbPolyNodes = aFaceNodes.Length();
- norm.SetCoord( 0, 0, 0 );
- if( IsReflected )
+ 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)
{
- 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 ) );
+ 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]);
}
- // compute normal
- // if( !MeshVS_Tool::GetNormal( PolyNodes, norm ) )
- // norm.SetCoord( 0, 0, 0 );
- MeshVS_Tool::GetAverageNormal( PolyNodes, norm );
+ aPolyNodes.SetValue (3 * aNodeIdx + 1, aX);
+ aPolyNodes.SetValue (3 * aNodeIdx + 2, aY);
+ aPolyNodes.SetValue (3 * aNodeIdx + 3, aZ);
}
+
+ gp_Vec aNorm;
- Standard_Real nx = norm.X(), ny = norm.Y(), nz = norm.Z();
-
-
- for( Standard_Integer j=1; j<=m; j++ )
+ if (theIsShaded)
{
- 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 );
+ aPolyNodes.SetValue (0, aNbPolyNodes);
+
+ if (!MeshVS_Tool::GetAverageNormal (aPolyNodes, aNorm))
+ {
+ aNorm.SetCoord (0.0, 0.0, 1.0);
+ }
+ }
- if( IsShrinked )
+ for (Standard_Integer aNodeIdx = 0; aNodeIdx < aNbPolyNodes - 2; ++aNodeIdx) // triangulate polygon
+ {
+ for (Standard_Integer aSubIdx = 0; aSubIdx < 3; ++aSubIdx) // generate sub-triangle
{
- 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] );
+ 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
+ {
+ 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));
+ }
}
-
- if( IsReflected )
- Array->AddVertex( x[0], y[0], z[0], nx, ny, nz );
- else
- Array->AddVertex( x[0], y[0], z[0] );
}
}
}
- else if( IsSelect )
+ else if (theIsSelected)
{
- 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 );
- Standard_Real pc[3]; pc[0] = pc[1] = pc[2] = 0;
- Standard_Integer j,m;
- for( j=1, m=aSeq.Length(); j<=m; j++ )
+ const TColStd_SequenceOfInteger& aFaceNodes = theTopo->Value (aFaceIdx);
+
+ Standard_Real aFaceCenter[] = { 0.0, 0.0, 0.0 };
+
+ for (Standard_Integer aNodeIdx = 1; aNodeIdx <= aFaceNodes.Length(); ++aNodeIdx)
{
- ind = aSeq.Value( j );
- for( Standard_Integer k=0; k<3; k++ )
- pc[k] += Nodes.Value( low + 3*ind+k );
+ for (Standard_Integer aAxisIdx = 0; aAxisIdx < 3; ++aAxisIdx)
+ {
+ aFaceCenter[aAxisIdx] += theNodes.Value (aLow + 3 * aFaceNodes.Value (aNodeIdx) + aAxisIdx);
+ }
}
- pc[0] /= m;
- pc[1] /= m;
- pc[2] /= m;
- Array->AddBound( m+1 );
- for( j=1, m=aSeq.Length(); j<=m+1; j++ )
+ aFaceCenter[0] /= aFaceNodes.Length();
+ aFaceCenter[1] /= aFaceNodes.Length();
+ aFaceCenter[2] /= aFaceNodes.Length();
+
+ for (Standard_Integer aNodeIdx = 0, aNbNodes = aFaceNodes.Length(); aNodeIdx < aNbNodes; ++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 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);
-
- 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 );
-
- if( IsShrinked )
- for( k=0; k<2; k++ )
+ const Standard_Integer anIdx1 = aLow + 3 * anIt.Key().first;
+ const Standard_Integer anIdx2 = aLow + 3 * anIt.Key().second;
+
+ 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 (theIsShrinked)
+ {
+ for (Standard_Integer anAxisIdx = 0; anAxisIdx < 2; ++anAxisIdx)
{
- 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] );
+ 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]);
}
}
}
// 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,
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
---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;
#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>
#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>
#include <Quantity_Array1OfColor.hxx>
#include <Aspect_SequenceOfColor.hxx>
+#include <NCollection_Map.hxx>
+#include <NCollection_Vector.hxx>
+
/*
Class : MeshVS_ImageTexture2D
Description : Texture for nodal presentation
(!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();
( 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();
// 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 ) );
- }
- else
- aCPolyArr->AddVertex( P, aDefNorm,
- gp_Pnt2d( aWrapCoord, aTexCoord >= 0 && aTexCoord <= 1 ? 0.75 : 0.25 ) );
- }
- else
- {
- GetColor ( aNodes( i ), aNColor );
+ 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 ( 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 )
+ if (aTestNorm.SquareMagnitude() > aMin)
{
- 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 );
+ aNorm = gp_Dir (aTestNorm);
}
- else
- aCPolyArr->AddVertex(P, aDefNorm, aNColor );
}
- else
- aCPolyArr->AddVertex( P, aNColor );
- }
- aPolyL->AddVertex ( P );
- if ( i == 1 )
- Start = P;
- }
- aPolyL->AddVertex ( Start );
- // 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;
-
- // 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 )
+ 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 ) );
+ 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( ind + 1 ), aNColor );
- if ( IsReflect )
+ 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 )
- {
- 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 );
+ aNColor.SetValues (anColorRatio * aNColor.Red(),
+ anColorRatio * aNColor.Green(),
+ anColorRatio * aNColor.Blue(),
+ Quantity_TOC_RGB);
+
+ aFaceTriangles->AddVertex (aPnt, aNorm, aNColor);
}
else
- aCPolyArr->AddVertex( P, aNColor );
+ {
+ aFaceTriangles->AddVertex (aPnt, aNColor);
+ }
}
- aPolyL->AddVertex ( P );
- if ( j == 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)
+ {
+ if (!aSource->Get3DGeom (aKey, NbNodes, aTopo))
+ continue;
+
+ 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);
}
}
} // for ( ...
Handle(Graphic3d_Group) aGroup1 = Prs3d_Root::CurrentGroup ( Prs );
aGroup1->SetPrimitivesAspect( anAsp );
- aGroup1->AddPrimitiveArray( aCPolyArr );
+ aGroup1->AddPrimitiveArray( aFaceTriangles /*aCPolyArr*/ );
+ //aGroup1->AddPrimitiveArray( aCPolyArr );
if (aShowEdges)
{
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 :
--- /dev/null
+#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
\ No newline at end of file
#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>
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;
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 )
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 );
-
- aVGroup->SetPrimitivesAspect( aFillAspect );
+ Handle(Graphic3d_AspectLine3d) anArrowLinAspect =
+ new Graphic3d_AspectLine3d (aColor, Aspect_TOL_SOLID, mySimpleWidthPrm);
+
+ aVGroup->SetPrimitivesAspect( anArrowLinAspect );
aVGroup->AddPrimitiveArray( aTriangleArray );
}
else
// 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]);
}
}