0031174: Visualization - support user-provided stipple line patterns
authorkgv <kgv@opencascade.com>
Mon, 18 Nov 2019 10:42:06 +0000 (13:42 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 21 Nov 2019 14:40:58 +0000 (17:40 +0300)
12 files changed:
src/Graphic3d/Graphic3d_AspectLine3d.cxx
src/Graphic3d/Graphic3d_AspectLine3d.hxx
src/Graphic3d/Graphic3d_Aspects.cxx
src/Graphic3d/Graphic3d_Aspects.hxx
src/OpenGl/OpenGl_Context.cxx
src/OpenGl/OpenGl_Context.hxx
src/OpenGl/OpenGl_PrimitiveArray.cxx
src/OpenGl/OpenGl_Workspace.cxx
src/ViewerTest/ViewerTest.cxx
src/ViewerTest/ViewerTest.hxx
tests/v3d/glsl/stipple_line1 [moved from tests/v3d/glsl/stipple_line with 100% similarity]
tests/v3d/glsl/stipple_line2 [new file with mode: 0644]

index 33db0ac..757c347 100644 (file)
@@ -39,6 +39,6 @@ Graphic3d_AspectLine3d::Graphic3d_AspectLine3d (const Quantity_Color& theColor,
 {
   myShadingModel = Graphic3d_TOSM_UNLIT;
   myInteriorColor.SetRGB (theColor);
-  myLineType = theType;
+  SetLineType (theType);
   SetLineWidth ((float)theWidth);
 }
index b90051c..1325427 100644 (file)
@@ -46,7 +46,7 @@ public:
   Aspect_TypeOfLine Type() const { return myLineType; }
 
   //! Modifies the type of line.
-  void SetType (const Aspect_TypeOfLine theType) { myLineType = theType; }
+  void SetType (const Aspect_TypeOfLine theType) { SetLineType (theType); }
 
   //! Return line width.
   Standard_ShortReal Width() const { return myLineWidth; }
index 667b773..56ddc52 100644 (file)
@@ -30,6 +30,7 @@ Graphic3d_Aspects::Graphic3d_Aspects()
   myAlphaCutoff         (0.5f),
   myLineType            (Aspect_TOL_SOLID),
   myLineWidth           (1.0f),
+  myLinePattern         (0xFFFF),
   myMarkerType          (Aspect_TOM_POINT),
   myMarkerScale         (1.0f),
   myTextStyle           (Aspect_TOST_NORMAL),
index adf5ea3..0764f88 100644 (file)
@@ -238,7 +238,21 @@ public:
   Aspect_TypeOfLine LineType() const { return myLineType; }
 
   //! Modifies the line type
-  void SetLineType (Aspect_TypeOfLine theType) { myLineType = theType; }
+  void SetLineType (Aspect_TypeOfLine theType)
+  {
+    myLineType = 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)
+  {
+    myLineType = DefaultLineTypeForPattern (thePattern);
+    myLinePattern = thePattern;
+  }
 
   //! Return width for edges in pixels; 1.0 by default.
   Standard_ShortReal LineWidth() const { return myLineWidth; }
@@ -254,6 +268,36 @@ public:
     myLineWidth = theWidth;
   }
 
+  //! 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;
+  }
+
 //! @name parameters specific to Point (Marker) primitive rendering
 public:
 
@@ -388,7 +432,7 @@ public:
   Aspect_TypeOfLine EdgeLineType() const { return myLineType; }
 
   //! Modifies the edge line type (same as SetLineType())
-  void SetEdgeLineType (Aspect_TypeOfLine theType) { myLineType = theType; }
+  void SetEdgeLineType (Aspect_TypeOfLine theType) { SetLineType (theType); }
 
   //! Return width for edges in pixels (same as LineWidth()).
   Standard_ShortReal EdgeWidth() const { return myLineWidth; }
@@ -459,6 +503,7 @@ public:
         && myLineType  == theOther.myLineType
         && myEdgeColor == theOther.myEdgeColor
         && myLineWidth == theOther.myLineWidth
+        && myLinePattern == theOther.myLinePattern
         && myMarkerType == theOther.myMarkerType
         && myMarkerScale == theOther.myMarkerScale
         && myHatchStyle == theOther.myHatchStyle
@@ -502,6 +547,7 @@ protected:
 
   Aspect_TypeOfLine            myLineType;
   Standard_ShortReal           myLineWidth;
+  uint16_t                     myLinePattern;
 
   Aspect_TypeOfMarker          myMarkerType;
   Standard_ShortReal           myMarkerScale;
index f71c55e..d61be5b 100644 (file)
@@ -3681,51 +3681,30 @@ 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_Aspects::DefaultLinePatternForType (theType));
+}
 
+// =======================================================================
+// function : SetLineStipple
+// purpose  :
+// =======================================================================
+void OpenGl_Context::SetLineStipple (const Standard_ShortReal theFactor,
+                                     const uint16_t thePattern)
+{
   if (!myActiveProgram.IsNull())
   {
     if (const OpenGl_ShaderUniformLocation aPatternLoc = myActiveProgram->GetStateLocation (OpenGl_OCCT_LINE_STIPPLE_PATTERN))
     {
       if (hasGlslBitwiseOps != OpenGl_FeatureNotAvailable)
       {
-        myActiveProgram->SetUniform (this, aPatternLoc, aPattern);
+        myActiveProgram->SetUniform (this, aPatternLoc, (Standard_Integer )thePattern);
       }
       else
       {
         Standard_Integer aPatArr[16] = {};
         for (unsigned int aBit = 0; aBit < 16; ++aBit)
         {
-          aPatArr[aBit] = ((unsigned int)(aPattern) & (1U << aBit)) != 0 ? 1 : 0;
+          aPatArr[aBit] = ((unsigned int)(thePattern) & (1U << aBit)) != 0 ? 1 : 0;
         }
         myActiveProgram->SetUniform (this, aPatternLoc, 16, aPatArr);
       }
@@ -3735,14 +3714,14 @@ void OpenGl_Context::SetTypeOfLine (const Aspect_TypeOfLine  theType,
   }
 
 #if !defined(GL_ES_VERSION_2_0)
-  if (aPattern != 0xFFFF)
+  if (thePattern != 0xFFFF)
   {
     if (core11 != NULL)
     {
       core11fwd->glEnable (GL_LINE_STIPPLE);
 
       core11->glLineStipple (static_cast<GLint>    (theFactor),
-                             static_cast<GLushort> (aPattern));
+                             static_cast<GLushort> (thePattern));
     }
   }
   else
index 127ecfe..a7c4215 100644 (file)
@@ -843,6 +843,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);
 
index cec64bb..97a6f39 100644 (file)
@@ -535,7 +535,7 @@ void OpenGl_PrimitiveArray::drawEdges (const Handle(OpenGl_Workspace)& theWorksp
   aGlContext->SetColor4fv (theWorkspace->EdgeColor().a() >= 0.1f
                          ? theWorkspace->EdgeColor()
                          : theWorkspace->View()->BackgroundColor());
-  aGlContext->SetTypeOfLine (anAspect->Aspect()->EdgeLineType());
+  aGlContext->SetLineStipple(anAspect->Aspect()->LinePattern());
   aGlContext->SetLineWidth  (anAspect->Aspect()->EdgeWidth());
 
   if (!myVboIndices.IsNull())
@@ -926,7 +926,7 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace
       if (myDrawMode == GL_LINES
        || myDrawMode == GL_LINE_STRIP)
       {
-        aCtx->SetTypeOfLine (anAspectFace->Aspect()->LineType());
+        aCtx->SetLineStipple(anAspectFace->Aspect()->LinePattern());
         aCtx->SetLineWidth  (anAspectFace->Aspect()->LineWidth());
       }
 
index 22f1449..8e6e308 100644 (file)
@@ -198,7 +198,7 @@ void OpenGl_Workspace::ResetAppliedAspect()
   myGlContext->SetPolygonOffset (Graphic3d_PolygonOffset());
 
   ApplyAspects();
-  myGlContext->SetTypeOfLine (myDefaultAspects.Aspect()->LineType());
+  myGlContext->SetLineStipple(myDefaultAspects.Aspect()->LinePattern());
   myGlContext->SetLineWidth  (myDefaultAspects.Aspect()->LineWidth());
   if (myGlContext->core15fwd != NULL)
   {
index e188566..fad405c 100644 (file)
@@ -338,43 +338,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_Aspects::DefaultLinePatternForType (theType);
   }
-  else if (aTypeStr == "solid")
+  else if (aTypeStr == "solid"
+        || aTypeStr == "0")
   {
     theType = Aspect_TOL_SOLID;
+    thePattern = Graphic3d_Aspects::DefaultLinePatternForType (theType);
   }
-  else if (aTypeStr == "dot")
+  else if (aTypeStr == "dot"
+        || aTypeStr == "2")
   {
     theType = Aspect_TOL_DOT;
+    thePattern = Graphic3d_Aspects::DefaultLinePatternForType (theType);
   }
-  else if (aTypeStr == "dash")
+  else if (aTypeStr == "dash"
+        || aTypeStr == "1")
   {
     theType = Aspect_TOL_DASH;
+    thePattern = Graphic3d_Aspects::DefaultLinePatternForType (theType);
   }
-  else if (aTypeStr == "dotdash")
+  else if (aTypeStr == "dotdash"
+        || aTypeStr == "3")
   {
     theType = Aspect_TOL_DOTDASH;
+    thePattern = Graphic3d_Aspects::DefaultLinePatternForType (theType);
   }
-  else if (aTypeStr.IsIntegerValue())
+  else
   {
-    const int aTypeInt = aTypeStr.IntegerValue();
-    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<unsigned char> (aTypeStr.Value (1)))
+    || !std::isxdigit (static_cast<unsigned char> (aTypeStr.Value (2)))
+    || !std::isxdigit (static_cast<unsigned char> (aTypeStr.Value (3)))
+    || !std::isxdigit (static_cast<unsigned char> (aTypeStr.Value (4))))
     {
       return Standard_False;
     }
-    theType = (Aspect_TypeOfLine )aTypeInt;
-  }
-  else
-  {
-    return Standard_False;
+
+    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_Aspects::DefaultLineTypeForPattern (thePattern);
   }
   return Standard_True;
 }
@@ -1783,7 +1814,7 @@ struct ViewerTest_AspectsChangeSet
   Standard_Real                LineWidth;
 
   Standard_Integer             ToSetTypeOfLine;
-  Aspect_TypeOfLine            TypeOfLine;
+  uint16_t                     StippleLinePattern;
 
   Standard_Integer             ToSetTypeOfMarker;
   Aspect_TypeOfMarker          TypeOfMarker;
@@ -1869,7 +1900,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),
@@ -2051,11 +2082,11 @@ struct ViewerTest_AspectsChangeSet
        || theDrawer->HasOwnSeenLineAspect())
       {
         toRecompute = theDrawer->SetOwnLineAspects() || toRecompute;
-        theDrawer->LineAspect()->SetTypeOfLine           (TypeOfLine);
-        theDrawer->WireAspect()->SetTypeOfLine           (TypeOfLine);
-        theDrawer->FreeBoundaryAspect()->SetTypeOfLine   (TypeOfLine);
-        theDrawer->UnFreeBoundaryAspect()->SetTypeOfLine (TypeOfLine);
-        theDrawer->SeenLineAspect()->SetTypeOfLine       (TypeOfLine);
+        theDrawer->LineAspect()->Aspect()->SetLinePattern (StippleLinePattern);
+        theDrawer->WireAspect()->Aspect()->SetLinePattern (StippleLinePattern);
+        theDrawer->FreeBoundaryAspect()->Aspect()->SetLinePattern (StippleLinePattern);
+        theDrawer->UnFreeBoundaryAspect()->Aspect()->SetLinePattern (StippleLinePattern);
+        theDrawer->SeenLineAspect()->Aspect()->SetLinePattern (StippleLinePattern);
       }
     }
     if (ToSetTypeOfMarker != 0)
@@ -2777,18 +2808,20 @@ static Standard_Integer VAspects (Draw_Interpretor& theDI,
         return 1;
       }
       Aspect_TypeOfLine aLineType = Aspect_TOL_EMPTY;
-      if (!ViewerTest::ParseLineType (theArgVec[anArgIter], aLineType))
+      uint16_t aLinePattern = 0xFFFF;
+      if (!ViewerTest::ParseLineType (theArgVec[anArgIter], aLineType, aLinePattern))
       {
         std::cout << "Error: wrong syntax at " << anArg << "\n";
         return 1;
       }
+
       if (anArg == "-setedgetype"
        || anArg == "-setedgestype"
        || anArg == "-edgetype"
        || anArg == "-edgestype"
        || aCmdName == "vsetedgetype")
       {
-        aChangeSet->TypeOfEdge = aLineType;
+        aChangeSet->TypeOfEdge = Graphic3d_Aspects::DefaultLineTypeForPattern (aLinePattern);
         aChangeSet->ToSetTypeOfEdge = 1;
       }
       else if (anArg == "-setfaceboundarystyle"
@@ -2800,12 +2833,12 @@ static Standard_Integer VAspects (Draw_Interpretor& theDI,
             || anArg == "-boundarytype"
             || aCmdName == "vshowfaceboundary")
       {
-        aChangeSet->TypeOfFaceBoundaryLine = aLineType;
+        aChangeSet->TypeOfFaceBoundaryLine = Graphic3d_Aspects::DefaultLineTypeForPattern (aLinePattern);
         aChangeSet->ToSetTypeOfFaceBoundaryLine = 1;
       }
       else
       {
-        aChangeSet->TypeOfLine = aLineType;
+        aChangeSet->StippleLinePattern = aLinePattern;
         aChangeSet->ToSetTypeOfLine = 1;
       }
     }
@@ -3256,7 +3289,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;
@@ -6660,7 +6693,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]"
index 0d1301b..37ef94c 100644 (file)
@@ -197,8 +197,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_line2 b/tests/v3d/glsl/stipple_line2
new file mode 100644 (file)
index 0000000..ba3a3ba
--- /dev/null
@@ -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