]> OCCT Git - occt.git/commitdiff
0021753: Visualization - improve shaded display of conical objects
authordrochalo <diogo.lopes@opencascade.com>
Wed, 18 Oct 2023 16:27:27 +0000 (17:27 +0100)
committerdrochalo <diogo.lopes@opencascade.com>
Wed, 18 Oct 2023 16:27:27 +0000 (17:27 +0100)
Removed bad seams from full cone by averaging top vertex normals. Tuned cone mesh subdivision parameters.

src/BRepMesh/BRepMesh_ConeRangeSplitter.cxx
src/StdPrs/StdPrs_ShadedShape.cxx

index cc61eedb9d1a8e72845319c78f1f1812de33359b..0e0be073db02afacdbbc125b8db4171de7abbd4b 100644 (file)
@@ -35,13 +35,17 @@ std::pair<Standard_Real, Standard_Real> BRepMesh_ConeRangeSplitter::GetSplitStep
   Standard_Real aRadius = Max(Abs(aRefR + aRangeV.first  * Sin(aSAng)),
                               Abs(aRefR + aRangeV.second * Sin(aSAng)));
 
+  //Face deflection used to determine circle subdivisions needs to match the one used previously
   Standard_Real Dv, Du = GCPnts_TangentialDeflection::ArcAngularStep(
-    aRadius, GetDFace()->GetDeflection(),
+    aRadius, GetDFace()->GetDeflection()*0.5,
     theParameters.Angle, theParameters.MinSize);
 
   const Standard_Real aDiffU = aRangeU.second - aRangeU.first;
   const Standard_Real aDiffV = aRangeV.second - aRangeV.first;
-  const Standard_Real aScale = (Du * aRadius);
+  //compute subdivision factor acounting for the difference between the bottom and top radius of the cone
+  const Standard_Real aTopRadius = aRefR > Precision::Confusion() ? aRefR : 1.0;
+  const Standard_Real aSubDivFactor = Max(theParameters.MinSize, Min(1.0, aTopRadius > aRadius ? aRadius / aTopRadius : aTopRadius / aRadius));
+  const Standard_Real aScale = (Du * aRadius * aSubDivFactor);
   const Standard_Real aRatio = Max(1., Log(aDiffV / aScale));
   const Standard_Integer nbU = (Standard_Integer)(aDiffU / Du);
   const Standard_Integer nbV = (Standard_Integer)(aDiffV / aScale / aRatio);
index fe2f667dbaa83aeb51e391400e8e172c3a37c4db..3e56277c1bebda41b21f1e782e63f9273b49c748 100644 (file)
@@ -192,6 +192,29 @@ namespace
       }
 
       const Standard_Integer aDecal = anArray->VertexNumber();
+      //check for duplicated vertices in the same face and average the normals
+      //to remove potential bad seams
+      for (Standard_Integer aNodeIter = 1; aNodeIter <= aT->NbNodes(); ++aNodeIter)
+      {
+        aPoint = aT->Node(aNodeIter);
+        gp_Dir aNorm = aT->Normal(aNodeIter);
+        for (Standard_Integer aSeekPtr = aNodeIter - 1; aSeekPtr > 0; --aSeekPtr)
+        {
+          gp_Pnt aMatchPnt = aT->Node(aSeekPtr);
+          gp_Dir aMatchNormal = aT->Normal(aSeekPtr);
+          if (aMatchPnt.Distance(aPoint) < Precision::Confusion())
+          {
+            gp_Vec aAuxVec((aNorm.X() + aMatchNormal.X()) * 0.5,
+                             (aNorm.Y() + aMatchNormal.Y()) * 0.5,
+                             (aNorm.Z() + aMatchNormal.Z()) * 0.5);
+            aAuxVec.Normalize();
+            gp_Dir aNewNormal(aAuxVec.X(), aAuxVec.Y(), aAuxVec.Z());
+            aT->SetNormal(aNodeIter, aNewNormal);
+            aT->SetNormal(aSeekPtr, aNewNormal);
+          }
+        }
+      }
+
       for (Standard_Integer aNodeIter = 1; aNodeIter <= aT->NbNodes(); ++aNodeIter)
       {
         aPoint = aT->Node (aNodeIter);
@@ -210,9 +233,9 @@ namespace
         {
           const gp_Pnt2d aNode2d = aT->UVNode (aNodeIter);
           const gp_Pnt2d aTexel = (dUmax == 0.0 || dVmax == 0.0)
-                                ? aNode2d
-                                : gp_Pnt2d ((-theUVOrigin.X() + (theUVRepeat.X() * (aNode2d.X() - aUmin)) / dUmax) / theUVScale.X(),
-                                            (-theUVOrigin.Y() + (theUVRepeat.Y() * (aNode2d.Y() - aVmin)) / dVmax) / theUVScale.Y());
+            ? aNode2d
+            : gp_Pnt2d ((-theUVOrigin.X() + (theUVRepeat.X() * (aNode2d.X() - aUmin)) / dUmax) / theUVScale.X(),
+              (-theUVOrigin.Y() + (theUVRepeat.Y() * (aNode2d.Y() - aVmin)) / dVmax) / theUVScale.Y());
           anArray->AddVertex (aPoint, aNorm, aTexel);
         }
         else