diff --git a/src/MeshVS/MeshVS_NodalColorPrsBuilder.cxx b/src/MeshVS/MeshVS_NodalColorPrsBuilder.cxx index 9cc72800e3..8900bb86df 100755 --- a/src/MeshVS/MeshVS_NodalColorPrsBuilder.cxx +++ b/src/MeshVS/MeshVS_NodalColorPrsBuilder.cxx @@ -74,7 +74,7 @@ MeshVS_ImageTexture2D::MeshVS_ImageTexture2D const Handle(AlienImage_AlienImage)& theImg) : Graphic3d_Texture2D( theSM, "", Graphic3d_TOT_2D ) { - MyCInitTexture.doModulate = 0/*1*/; + MyCInitTexture.doModulate = 1; MyCInitTexture.doRepeat = 0; MyCInitTexture.Mode = (int)Graphic3d_TOTM_MANUAL; MyCInitTexture.doLinear = 1; @@ -178,10 +178,6 @@ void MeshVS_NodalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)& Prs, aDrawer->GetBoolean( MeshVS_DA_ColorReflection, IsReflect ); aDrawer->GetBoolean( MeshVS_DA_SmoothShading, IsMeshSmoothShading ); - // NOTE: Lighting effect not tested with textures, so turning off reflectance when textures are used. - // This can be improved if necessary... - IsReflect = IsReflect && !myUseTexture; - // Following parameter are used for texture presentation only int nbColors = 0; // Number of colors from color map int nbTextureColors = 0; // Number of colors in texture (it will be pow of 2) @@ -307,10 +303,29 @@ void MeshVS_NodalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)& Prs, // transform texture coordinate in accordance with number of colors specified // by upper level and real size of Gl texture - aTexCoord = aTexCoord * nbColors / nbTextureColors; + // 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; - aCPolyArr->AddVertex( P, aDefNorm, - gp_Pnt2d( aTexCoord, aTexCoord >= 0 && aTexCoord <= 1 ? 1 : 0 ) ); + 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 { @@ -377,10 +392,29 @@ void MeshVS_NodalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)& Prs, // transform texture coordinate in accordance with number of colors specified // by upper level and real size of Gl texture - aTexCoord = aTexCoord * nbColors / nbTextureColors; + // 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_Pnt2d aTP( aTexCoord, aTexCoord >= 0 && aTexCoord <= 1 ? 1 : 0 ); - aCPolyArr->AddVertex( P, aDefNorm, aTP ); + 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 { @@ -464,6 +498,7 @@ void MeshVS_NodalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)& Prs, anAsp->SetTextureMapOn(); anAsp->SetTextureMap( aTexture ); + anAsp->SetInteriorColor( Quantity_NOC_WHITE ); } else { @@ -477,7 +512,6 @@ void MeshVS_NodalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)& Prs, anAsp->SetDistinguishOff(); anAsp->SetEdgeOff(); - anAsp->SetInteriorColor( Quantity_NOC_GRAY ); Handle(Graphic3d_AspectLine3d) anLAsp = new Graphic3d_AspectLine3d( anEdgeColor, anEdgeType, anEdgeWidth ); diff --git a/src/XSDRAWSTLVRML/XSDRAWSTLVRML.cxx b/src/XSDRAWSTLVRML/XSDRAWSTLVRML.cxx index a2ec688e24..93fafe7745 100755 --- a/src/XSDRAWSTLVRML/XSDRAWSTLVRML.cxx +++ b/src/XSDRAWSTLVRML/XSDRAWSTLVRML.cxx @@ -58,7 +58,8 @@ #include #include #include - +#include +#include // avoid warnings on 'extern "C"' functions returning C++ classes #ifdef WNT @@ -714,10 +715,11 @@ static Standard_Integer meshcolors( Draw_Interpretor& di, if ( argc < 2 ) { di << "Use : meshcolors meshname mode isreflect" << "\n"; - di << "mode : {elem1|elem2|nodal|none}"<< "\n"; + di << "mode : {elem1|elem2|nodal|nodaltex|none}"<< "\n"; di << " elem1 - different color for each element" << "\n"; di << " elem2 - one color for one side"<<"\n"; - di << " nodal - different color for each node"<< "\n"; + di << " nodal - different color for each node"<< "\n"; + di << " nodaltex - different color for each node with texture interpolation"<< "\n"; di << " none - clear"<< "\n"; di << "isreflect : {0|1} "<< "\n"; @@ -742,7 +744,7 @@ static Standard_Integer meshcolors( Draw_Interpretor& di, TCollection_AsciiString aMode = TCollection_AsciiString (argv[2]); Quantity_Color aColor1( (Quantity_NameOfColor)( Quantity_NOC_BLUE1 ) ); Quantity_Color aColor2( (Quantity_NameOfColor)( Quantity_NOC_RED1 ) ); - if( aMode.IsEqual("elem1") || aMode.IsEqual("elem2") || aMode.IsEqual("nodal") || aMode.IsEqual("none") ) + if( aMode.IsEqual("elem1") || aMode.IsEqual("elem2") || aMode.IsEqual("nodal") || aMode.IsEqual("nodaltex") || aMode.IsEqual("none") ) { Handle(MeshVS_PrsBuilder) aTempBuilder; Standard_Integer reflection = atoi(argv[3]); @@ -798,6 +800,67 @@ static Standard_Integer meshcolors( Draw_Interpretor& di, aMesh->AddBuilder( aBuilder, Standard_True ); } + if(aMode.IsEqual("nodaltex")) + { + // assign nodal builder to the mesh + Handle(MeshVS_NodalColorPrsBuilder) aBuilder = new MeshVS_NodalColorPrsBuilder( + aMesh, MeshVS_DMF_NodalColorDataPrs | MeshVS_DMF_OCCMask); + aMesh->AddBuilder(aBuilder, Standard_True); + aBuilder->UseTexture(Standard_True); + + // prepare color map for texture + Aspect_SequenceOfColor aColorMap; + aColorMap.Append((Quantity_NameOfColor) Quantity_NOC_RED); + aColorMap.Append((Quantity_NameOfColor) Quantity_NOC_YELLOW); + aColorMap.Append((Quantity_NameOfColor) Quantity_NOC_BLUE1); + + // prepare scale map for mesh - it will be assigned to mesh as texture coordinates + // make mesh color interpolated from minimum X coord to maximum X coord + Handle(MeshVS_DataSource) aDataSource = aMesh->GetDataSource(); + Standard_Real aMinX, aMinY, aMinZ, aMaxX, aMaxY, aMaxZ; + + // get bounding box for calculations + aDataSource->GetBoundingBox().Get(aMinX, aMinY, aMinZ, aMaxX, aMaxY, aMaxZ); + Standard_Real aDelta = aMaxX - aMinX; + + // assign color scale map values (0..1) to nodes + TColStd_DataMapOfIntegerReal aScaleMap; + TColStd_Array1OfReal aCoords(1, 3); + Standard_Integer aNbNodes; + MeshVS_EntityType aType; + + // iterate nodes + const TColStd_PackedMapOfInteger& anAllNodes = + aMesh->GetDataSource()->GetAllNodes(); + TColStd_MapIteratorOfPackedMapOfInteger anIter(anAllNodes); + for (; anIter.More(); anIter.Next()) + { + //get node coordinates to aCoord variable + aDataSource->GetGeom(anIter.Key(), Standard_False, aCoords, aNbNodes, aType); + + Standard_Real aScaleValue; + try { + OCC_CATCH_SIGNALS + aScaleValue = (aCoords.Value(1) - (Standard_Real) aMinX) / aDelta; + } catch(Standard_Failure) { + aScaleValue = 0; + } + + aScaleMap.Bind(anIter.Key(), aScaleValue); + } + + //set color map for builder and a color for invalid scale value + aBuilder->SetColorMap(aColorMap); + aBuilder->SetInvalidColor(Quantity_NOC_BLACK); + aBuilder->SetTextureCoords(aScaleMap); + aMesh->AddBuilder(aBuilder, Standard_True); + + //set viewer to display texures + const Handle(V3d_Viewer)& aViewer = anIC->CurrentViewer(); + for (aViewer->InitActiveViews(); aViewer->MoreActiveViews(); aViewer->NextActiveViews()) + aViewer->ActiveView()->SetSurfaceDetail(V3d_TEX_ALL); + } + aMesh->GetDrawer()->SetBoolean ( MeshVS_DA_ColorReflection, Standard_Boolean(reflection) ); anIC->Redisplay( aMesh );