From 9cee51b43b30fa3d37b25fc52fb044b0c207c683 Mon Sep 17 00:00:00 2001 From: kgv Date: Mon, 18 Nov 2019 13:42:06 +0300 Subject: [PATCH] 0031174: Visualization - support user-provided stipple line patterns [occt720 backport] --- src/Graphic3d/Graphic3d_AspectLine3d.cxx | 6 +- src/Graphic3d/Graphic3d_AspectLine3d.hxx | 48 +++++++++- src/OpenGl/OpenGl_Context.cxx | 45 +++------- src/OpenGl/OpenGl_Context.hxx | 7 ++ src/OpenGl/OpenGl_PrimitiveArray.cxx | 4 +- src/OpenGl/OpenGl_Workspace.cxx | 2 +- src/ViewerTest/ViewerTest.cxx | 87 +++++++++++++------ src/ViewerTest/ViewerTest.hxx | 14 ++- .../v3d/glsl/{stipple_line => stipple_line1} | 0 tests/v3d/glsl/stipple_line2 | 15 ++++ 10 files changed, 162 insertions(+), 66 deletions(-) rename tests/v3d/glsl/{stipple_line => stipple_line1} (100%) create mode 100644 tests/v3d/glsl/stipple_line2 diff --git a/src/Graphic3d/Graphic3d_AspectLine3d.cxx b/src/Graphic3d/Graphic3d_AspectLine3d.cxx index c482b83fa1..bb760f3017 100644 --- a/src/Graphic3d/Graphic3d_AspectLine3d.cxx +++ b/src/Graphic3d/Graphic3d_AspectLine3d.cxx @@ -24,7 +24,8 @@ IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_AspectLine3d, Standard_Transient) Graphic3d_AspectLine3d::Graphic3d_AspectLine3d() : myColor (Quantity_NOC_YELLOW), myType (Aspect_TOL_SOLID), - myWidth (1.0f) + myWidth (1.0f), + myLinePattern (0xFFFF) { // } @@ -38,7 +39,8 @@ Graphic3d_AspectLine3d::Graphic3d_AspectLine3d (const Quantity_Color& theColor const Standard_Real theWidth) : myColor (theColor), myType (theType), - myWidth ((float )theWidth) + myWidth ((float )theWidth), + myLinePattern (DefaultLinePatternForType (theType)) { if (myWidth <= 0.0f) { diff --git a/src/Graphic3d/Graphic3d_AspectLine3d.hxx b/src/Graphic3d/Graphic3d_AspectLine3d.hxx index f21dfb905a..abf0cd7f22 100644 --- a/src/Graphic3d/Graphic3d_AspectLine3d.hxx +++ b/src/Graphic3d/Graphic3d_AspectLine3d.hxx @@ -61,7 +61,51 @@ public: Aspect_TypeOfLine Type() const { return myType; } //! Modifies the type of line. - void SetType (const Aspect_TypeOfLine theType) { myType = theType; } + void SetType (const Aspect_TypeOfLine theType) + { + myType = theType; + myLinePattern = DefaultLinePatternForType (theType); + } + + //! Return custom stipple line pattern; 0xFFFF by default. + uint16_t LinePattern() const { return myLinePattern; } + + //! Modifies the stipple line pattern, and changes line type to Aspect_TOL_USERDEFINED for non-standard pattern. + void SetLinePattern (uint16_t thePattern) + { + myType = DefaultLineTypeForPattern (thePattern); + myLinePattern = thePattern; + } + + //! Return stipple line pattern for line type. + static uint16_t DefaultLinePatternForType (Aspect_TypeOfLine theType) + { + switch (theType) + { + case Aspect_TOL_DASH: return 0xFFC0; + case Aspect_TOL_DOT: return 0xCCCC; + case Aspect_TOL_DOTDASH: return 0xFF18; + case Aspect_TOL_EMPTY: return 0x0000; + case Aspect_TOL_SOLID: return 0xFFFF; + case Aspect_TOL_USERDEFINED: return 0xFF24; + } + return 0xFFFF; + } + + //! Return line type for stipple line pattern. + static Aspect_TypeOfLine DefaultLineTypeForPattern (uint16_t thePattern) + { + switch (thePattern) + { + case 0x0000: return Aspect_TOL_EMPTY; + case 0xFFC0: return Aspect_TOL_DASH; + case 0xCCCC: return Aspect_TOL_DOT; + case 0xFF18: return Aspect_TOL_DOTDASH; + case 0xFFFF: return Aspect_TOL_SOLID; + case 0xFF24: return Aspect_TOL_USERDEFINED; + } + return Aspect_TOL_USERDEFINED; + } //! Return line width. Standard_ShortReal Width() const { return myWidth; } @@ -97,6 +141,7 @@ public: return myProgram == theOther.myProgram && myType == theOther.myType + && myLinePattern == theOther.myLinePattern && myColor == theOther.myColor && myWidth == theOther.myWidth; } @@ -120,6 +165,7 @@ protected: Quantity_ColorRGBA myColor; Aspect_TypeOfLine myType; Standard_ShortReal myWidth; + uint16_t myLinePattern; }; diff --git a/src/OpenGl/OpenGl_Context.cxx b/src/OpenGl/OpenGl_Context.cxx index 52f9a16050..7f7cc9f185 100644 --- a/src/OpenGl/OpenGl_Context.cxx +++ b/src/OpenGl/OpenGl_Context.cxx @@ -3264,46 +3264,25 @@ void OpenGl_Context::SetColor4fv (const OpenGl_Vec4& theColor) void OpenGl_Context::SetTypeOfLine (const Aspect_TypeOfLine theType, const Standard_ShortReal theFactor) { - Standard_Integer aPattern = 0xFFFF; - switch (theType) - { - case Aspect_TOL_DASH: - { - aPattern = 0xFFC0; - break; - } - case Aspect_TOL_DOT: - { - aPattern = 0xCCCC; - break; - } - case Aspect_TOL_DOTDASH: - { - aPattern = 0xFF18; - break; - } - case Aspect_TOL_EMPTY: - case Aspect_TOL_SOLID: - { - aPattern = 0xFFFF; - break; - } - case Aspect_TOL_USERDEFINED: - { - aPattern = 0xFF24; - break; - } - } + SetLineStipple (theFactor, Graphic3d_AspectLine3d::DefaultLinePatternForType (theType)); +} +// ======================================================================= +// function : SetLineStipple +// purpose : +// ======================================================================= +void OpenGl_Context::SetLineStipple (const Standard_ShortReal theFactor, + const uint16_t thePattern) +{ if (!myActiveProgram.IsNull()) { - myActiveProgram->SetUniform (this, "uPattern", aPattern); + myActiveProgram->SetUniform (this, "uPattern", (Standard_Integer )thePattern); myActiveProgram->SetUniform (this, "uFactor", theFactor); return; } #if !defined(GL_ES_VERSION_2_0) - if (aPattern != 0xFFFF) + if (thePattern != 0xFFFF) { #ifdef HAVE_GL2PS if (IsFeedback()) @@ -3317,7 +3296,7 @@ void OpenGl_Context::SetTypeOfLine (const Aspect_TypeOfLine theType, core11fwd->glEnable (GL_LINE_STIPPLE); core11->glLineStipple (static_cast (theFactor), - static_cast (aPattern)); + static_cast (thePattern)); } } else diff --git a/src/OpenGl/OpenGl_Context.hxx b/src/OpenGl/OpenGl_Context.hxx index 018fa460df..3a7ed542e3 100644 --- a/src/OpenGl/OpenGl_Context.hxx +++ b/src/OpenGl/OpenGl_Context.hxx @@ -680,6 +680,13 @@ public: //! @name methods to alter or retrieve current state Standard_EXPORT void SetTypeOfLine (const Aspect_TypeOfLine theType, const Standard_ShortReal theFactor = 1.0f); + //! Setup stipple line pattern with 1.0f factor; wrapper for glLineStipple(). + void SetLineStipple (const uint16_t thePattern) { SetLineStipple (1.0f, thePattern); } + + //! Setup type of line; wrapper for glLineStipple(). + Standard_EXPORT void SetLineStipple (const Standard_ShortReal theFactor, + const uint16_t thePattern); + //! Setup width of line. Standard_EXPORT void SetLineWidth (const Standard_ShortReal theWidth); diff --git a/src/OpenGl/OpenGl_PrimitiveArray.cxx b/src/OpenGl/OpenGl_PrimitiveArray.cxx index 97a3e4f2b0..bcf391e6e2 100644 --- a/src/OpenGl/OpenGl_PrimitiveArray.cxx +++ b/src/OpenGl/OpenGl_PrimitiveArray.cxx @@ -474,7 +474,7 @@ void OpenGl_PrimitiveArray::drawEdges (const OpenGl_Vec4& theEdgeCo myVboAttribs->BindPositionAttribute (aGlContext); aGlContext->SetColor4fv (theEdgeColour); - aGlContext->SetTypeOfLine (anAspect->Aspect()->Type()); + aGlContext->SetLineStipple(anAspect->Aspect()->LinePattern()); aGlContext->SetLineWidth (anAspect->Aspect()->Width()); if (!myVboIndices.IsNull()) @@ -833,7 +833,7 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace if (myDrawMode == GL_LINES || myDrawMode == GL_LINE_STRIP) { - aCtx->SetTypeOfLine (anAspectLine->Aspect()->Type()); + aCtx->SetLineStipple(anAspectLine->Aspect()->LinePattern()); aCtx->SetLineWidth (anAspectLine->Aspect()->Width()); } diff --git a/src/OpenGl/OpenGl_Workspace.cxx b/src/OpenGl/OpenGl_Workspace.cxx index a8a02385c6..d93f923621 100644 --- a/src/OpenGl/OpenGl_Workspace.cxx +++ b/src/OpenGl/OpenGl_Workspace.cxx @@ -224,7 +224,7 @@ void OpenGl_Workspace::ResetAppliedAspect() ApplyAspectMarker(); ApplyAspectText(); - myGlContext->SetTypeOfLine (myDefaultAspectLine.Aspect()->Type()); + myGlContext->SetLineStipple(myDefaultAspectLine.Aspect()->LinePattern()); myGlContext->SetLineWidth (myDefaultAspectLine.Aspect()->Width()); } diff --git a/src/ViewerTest/ViewerTest.cxx b/src/ViewerTest/ViewerTest.cxx index b61329afbf..26eb4d4741 100644 --- a/src/ViewerTest/ViewerTest.cxx +++ b/src/ViewerTest/ViewerTest.cxx @@ -188,39 +188,74 @@ void ViewerTest::GetSelectedShapes (TopTools_ListOfShape& theSelectedShapes) //function : ParseLineType //purpose : //======================================================================= -Standard_Boolean ViewerTest::ParseLineType (Standard_CString theArg, - Aspect_TypeOfLine& theType) +Standard_Boolean ViewerTest::ParseLineType (Standard_CString theArg, + Aspect_TypeOfLine& theType, + uint16_t& thePattern) { TCollection_AsciiString aTypeStr (theArg); aTypeStr.LowerCase(); - if (aTypeStr == "empty") + if (aTypeStr == "empty" + || aTypeStr == "-1") { theType = Aspect_TOL_EMPTY; + thePattern = Graphic3d_AspectLine3d::DefaultLinePatternForType (theType); } - else if (aTypeStr == "solid") + else if (aTypeStr == "solid" + || aTypeStr == "0") { theType = Aspect_TOL_SOLID; + thePattern = Graphic3d_AspectLine3d::DefaultLinePatternForType (theType); } - else if (aTypeStr == "dot") + else if (aTypeStr == "dot" + || aTypeStr == "2") { theType = Aspect_TOL_DOT; + thePattern = Graphic3d_AspectLine3d::DefaultLinePatternForType (theType); } - else if (aTypeStr == "dash") + else if (aTypeStr == "dash" + || aTypeStr == "1") { theType = Aspect_TOL_DASH; + thePattern = Graphic3d_AspectLine3d::DefaultLinePatternForType (theType); } - else if (aTypeStr == "dotdash") + else if (aTypeStr == "dotdash" + || aTypeStr == "3") { theType = Aspect_TOL_DOTDASH; + thePattern = Graphic3d_AspectLine3d::DefaultLinePatternForType (theType); } else { - const int aTypeInt = Draw::Atoi (theArg); - if (aTypeInt < -1 || aTypeInt >= Aspect_TOL_USERDEFINED) + if (aTypeStr.StartsWith ("0x")) + { + aTypeStr = aTypeStr.SubString (3, aTypeStr.Length()); + } + + if (aTypeStr.Length() != 4 + || !std::isxdigit (static_cast (aTypeStr.Value (1))) + || !std::isxdigit (static_cast (aTypeStr.Value (2))) + || !std::isxdigit (static_cast (aTypeStr.Value (3))) + || !std::isxdigit (static_cast (aTypeStr.Value (4)))) { return Standard_False; } - theType = (Aspect_TypeOfLine )aTypeInt; + + std::stringstream aStream; + aStream << std::setbase (16) << aTypeStr.ToCString(); + if (aStream.fail()) + { + return Standard_False; + } + + Standard_Integer aNumber = -1; + aStream >> aNumber; + if (aStream.fail()) + { + return Standard_False; + } + + thePattern = (uint16_t )aNumber; + theType = Graphic3d_AspectLine3d::DefaultLineTypeForPattern (thePattern); } return Standard_True; } @@ -1628,7 +1663,7 @@ struct ViewerTest_AspectsChangeSet Standard_Real LineWidth; Standard_Integer ToSetTypeOfLine; - Aspect_TypeOfLine TypeOfLine; + uint16_t StippleLinePattern; Standard_Integer ToSetTypeOfMarker; Aspect_TypeOfMarker TypeOfMarker; @@ -1674,7 +1709,7 @@ struct ViewerTest_AspectsChangeSet ToSetLineWidth (0), LineWidth (1.0), ToSetTypeOfLine (0), - TypeOfLine (Aspect_TOL_SOLID), + StippleLinePattern(0xFFFF), ToSetTypeOfMarker (0), TypeOfMarker (Aspect_TOM_PLUS), ToSetMarkerSize (0), @@ -2080,7 +2115,9 @@ static Standard_Integer VAspects (Draw_Interpretor& /*theDI*/, std::cout << "Error: wrong syntax at " << anArg << "\n"; return 1; } - if (!ViewerTest::ParseLineType (theArgVec[anArgIter], aChangeSet->TypeOfLine)) + + Aspect_TypeOfLine aLineType = Aspect_TOL_EMPTY; + if (!ViewerTest::ParseLineType (theArgVec[anArgIter], aLineType, aChangeSet->StippleLinePattern)) { std::cout << "Error: wrong syntax at " << anArg << "\n"; return 1; @@ -2302,7 +2339,7 @@ static Standard_Integer VAspects (Draw_Interpretor& /*theDI*/, aChangeSet->ToSetLineWidth = -1; aChangeSet->LineWidth = 1.0; aChangeSet->ToSetTypeOfLine = -1; - aChangeSet->TypeOfLine = Aspect_TOL_SOLID; + aChangeSet->StippleLinePattern = 0xFFFF; aChangeSet->ToSetTypeOfMarker = -1; aChangeSet->TypeOfMarker = Aspect_TOM_PLUS; aChangeSet->ToSetMarkerSize = -1; @@ -2455,11 +2492,11 @@ static Standard_Integer VAspects (Draw_Interpretor& /*theDI*/, } if (aChangeSet->ToSetTypeOfLine != 0) { - aDrawer->LineAspect()->SetTypeOfLine (aChangeSet->TypeOfLine); - aDrawer->WireAspect()->SetTypeOfLine (aChangeSet->TypeOfLine); - aDrawer->FreeBoundaryAspect()->SetTypeOfLine (aChangeSet->TypeOfLine); - aDrawer->UnFreeBoundaryAspect()->SetTypeOfLine (aChangeSet->TypeOfLine); - aDrawer->SeenLineAspect()->SetTypeOfLine (aChangeSet->TypeOfLine); + aDrawer->LineAspect()->Aspect()->SetLinePattern (aChangeSet->StippleLinePattern); + aDrawer->WireAspect()->Aspect()->SetLinePattern (aChangeSet->StippleLinePattern); + aDrawer->FreeBoundaryAspect()->Aspect()->SetLinePattern (aChangeSet->StippleLinePattern); + aDrawer->UnFreeBoundaryAspect()->Aspect()->SetLinePattern (aChangeSet->StippleLinePattern); + aDrawer->SeenLineAspect()->Aspect()->SetLinePattern (aChangeSet->StippleLinePattern); } if (aChangeSet->ToSetTypeOfMarker != 0) { @@ -2633,11 +2670,11 @@ static Standard_Integer VAspects (Draw_Interpretor& /*theDI*/, } if (aChangeSet->ToSetTypeOfLine != 0) { - aDrawer->LineAspect()->SetTypeOfLine (aChangeSet->TypeOfLine); - aDrawer->WireAspect()->SetTypeOfLine (aChangeSet->TypeOfLine); - aDrawer->FreeBoundaryAspect()->SetTypeOfLine (aChangeSet->TypeOfLine); - aDrawer->UnFreeBoundaryAspect()->SetTypeOfLine (aChangeSet->TypeOfLine); - aDrawer->SeenLineAspect()->SetTypeOfLine (aChangeSet->TypeOfLine); + aDrawer->LineAspect()->Aspect()->SetLinePattern (aChangeSet->StippleLinePattern); + aDrawer->WireAspect()->Aspect()->SetLinePattern (aChangeSet->StippleLinePattern); + aDrawer->FreeBoundaryAspect()->Aspect()->SetLinePattern (aChangeSet->StippleLinePattern); + aDrawer->UnFreeBoundaryAspect()->Aspect()->SetLinePattern (aChangeSet->StippleLinePattern); + aDrawer->SeenLineAspect()->Aspect()->SetLinePattern (aChangeSet->StippleLinePattern); toRedisplay = Standard_True; } if (aChangeSet->ToSetTypeOfMarker != 0) @@ -6217,7 +6254,7 @@ void ViewerTest::Commands(Draw_Interpretor& theCommands) "\n\t\t: [-setMaterial MatName] [-unsetMaterial]" "\n\t\t: [-setTransparency Transp] [-unsetTransparency]" "\n\t\t: [-setWidth LineWidth] [-unsetWidth]" - "\n\t\t: [-setLineType {solid|dash|dot|dotDash}] [-unsetLineType]" + "\n\t\t: [-setLineType {solid|dash|dot|dotDash|0xHexPattern}] [-unsetLineType]" "\n\t\t: [-setMarkerType {.|+|x|O|xcircle|pointcircle|ring1|ring2|ring3|ball|ImagePath}]" "\n\t\t: [-unsetMarkerType]" "\n\t\t: [-setMarkerSize Scale] [-unsetMarkerSize]" diff --git a/src/ViewerTest/ViewerTest.hxx b/src/ViewerTest/ViewerTest.hxx index 8a93b8a5bd..220930e92c 100644 --- a/src/ViewerTest/ViewerTest.hxx +++ b/src/ViewerTest/ViewerTest.hxx @@ -191,8 +191,18 @@ public: //! Parses line type argument. //! Handles either enumeration (integer) value or string constant. - Standard_EXPORT static Standard_Boolean ParseLineType (Standard_CString theArg, - Aspect_TypeOfLine& theType); + Standard_EXPORT static Standard_Boolean ParseLineType (Standard_CString theArg, + Aspect_TypeOfLine& theType, + uint16_t& thePattern); + + //! Parses line type argument. + //! Handles either enumeration (integer) value or string constant. + static Standard_Boolean ParseLineType (Standard_CString theArg, + Aspect_TypeOfLine& theType) + { + uint16_t aPattern = 0xFFFF; + return ParseLineType (theArg, theType, aPattern); + } //! Parses marker type argument. //! Handles either enumeration (integer) value or string constant. diff --git a/tests/v3d/glsl/stipple_line b/tests/v3d/glsl/stipple_line1 similarity index 100% rename from tests/v3d/glsl/stipple_line rename to tests/v3d/glsl/stipple_line1 diff --git a/tests/v3d/glsl/stipple_line2 b/tests/v3d/glsl/stipple_line2 new file mode 100644 index 0000000000..ba3a3ba33c --- /dev/null +++ b/tests/v3d/glsl/stipple_line2 @@ -0,0 +1,15 @@ +puts "========" +puts "0031174: Visualization - support user-provided stipple line patterns" +puts "========" +puts "" + +pload MODELING VISUALIZATION +box b1 1 2 3 +box b2 1 2 3 +vclear +vinit View1 +vdisplay -dispMode 0 b1 b2 +vfit +vaspects b1 -setLineWidth 4 -setLineType FF00 -setColor RED +vaspects b2 -setLineWidth 4 -setLineType 00FF -setColor GREEN +vdump $::imagedir/${::casename}_glsl.png