diff --git a/src/Mod/Part/Gui/DlgSettings3DViewPart.ui b/src/Mod/Part/Gui/DlgSettings3DViewPart.ui
index d4389d290..8b8a4c652 100644
--- a/src/Mod/Part/Gui/DlgSettings3DViewPart.ui
+++ b/src/Mod/Part/Gui/DlgSettings3DViewPart.ui
@@ -6,7 +6,7 @@
0
0
- 610
+ 525
339
@@ -53,26 +53,7 @@
6
- -
-
-
- Defines the appearance of surfaces
-
-
- <html><head><meta name="qrichtext" content="1" /></head><body style=" white-space: pre-wrap; font-family:MS Shell Dlg 2; font-size:7.8pt; font-weight:400; font-style:normal; text-decoration:none;"><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Flat shading/Phong shading</span></p><p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">With flat shading the surface normals are not defined per vertex that leads to a unreal appearance for curved surfaces while using Phong shading leads to a smoother appearance. </p><p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">If this option is unset Phong shading is used, if it is set flat shading is used.</p></body></html>
-
-
- Do not define normal per vertex
-
-
- NoPerVertexNormals
-
-
- Mod/Part
-
-
-
- -
+
-
Defines the deviation of tessellation to the actual surface
@@ -85,21 +66,7 @@
- -
-
-
- <html><head><meta name="qrichtext" content="1" /></head><body style=" white-space: pre-wrap; font-family:MS Shell Dlg 2; font-size:7.8pt; font-weight:400; font-style:normal; text-decoration:none;"><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><span style=" font-weight:600;">Hint</span></p><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;">Defining the normals per vertex is also called <span style=" font-style:italic;">Phong shading</span></p><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt; font-style:italic;"><span style=" font-style:normal;">while defining the normals per face is called </span>Flat shading<span style=" font-style:normal;">.</span></p></body></html>
-
-
-
- -
-
-
- View smoothing
-
-
-
- -
+
-
%
@@ -127,70 +94,6 @@
- -
-
-
- This will slow down render speed but will lead to nicer results
-
-
- <html><head><meta name="qrichtext" content="1" /></head><body style=" white-space: pre-wrap; font-family:MS Shell Dlg 2; font-size:7.8pt; font-weight:400; font-style:normal; text-decoration:none;"><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">High-quality normals</span></p><p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">This will slow down render speed but will lead to nicer results.</p></body></html>
-
-
- Using high-quality normals
-
-
- QualityNormals
-
-
- Mod/Part
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- QFrame::HLine
-
-
- QFrame::Sunken
-
-
- Qt::Horizontal
-
-
-
- -
-
-
- View accuracy / Performance
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- QFrame::HLine
-
-
- QFrame::Sunken
-
-
- Qt::Horizontal
-
-
-
@@ -200,11 +103,6 @@
-
- Gui::PrefCheckBox
- QCheckBox
-
-
Gui::PrefDoubleSpinBox
QDoubleSpinBox
diff --git a/src/Mod/Part/Gui/DlgSettings3DViewPartImp.cpp b/src/Mod/Part/Gui/DlgSettings3DViewPartImp.cpp
index 98b84f1db..846775ce3 100644
--- a/src/Mod/Part/Gui/DlgSettings3DViewPartImp.cpp
+++ b/src/Mod/Part/Gui/DlgSettings3DViewPartImp.cpp
@@ -70,8 +70,6 @@ void DlgSettings3DViewPart::on_maxDeviation_valueChanged(double v)
void DlgSettings3DViewPart::saveSettings()
{
ui->maxDeviation->onSave();
- ui->prefCheckBox8->onSave();
- ui->prefCheckBox3->onSave();
// search for Part view providers and apply the new settings
std::vector docs = App::GetApplication().getDocuments();
@@ -87,8 +85,6 @@ void DlgSettings3DViewPart::saveSettings()
void DlgSettings3DViewPart::loadSettings()
{
ui->maxDeviation->onRestore();
- ui->prefCheckBox8->onRestore();
- ui->prefCheckBox3->onRestore();
}
/**
diff --git a/src/Mod/Part/Gui/ViewProviderExt.cpp b/src/Mod/Part/Gui/ViewProviderExt.cpp
index ead6e02ca..02ad4c645 100644
--- a/src/Mod/Part/Gui/ViewProviderExt.cpp
+++ b/src/Mod/Part/Gui/ViewProviderExt.cpp
@@ -35,6 +35,7 @@
# include
# include
# include
+# include
# include
# include
# include
@@ -47,6 +48,7 @@
# include
# include
# include
+# include
# include
# include
# include
@@ -61,7 +63,13 @@
# include
# include
# include
+# include
+# include
# include
+# include
+# include
+# include
+
# include
# include
# include
@@ -119,6 +127,94 @@ using namespace PartGui;
PROPERTY_SOURCE(PartGui::ViewProviderPartExt, Gui::ViewProviderGeometryObject)
+void GetNormals(const TopoDS_Face& theFace,
+ const Handle(Poly_Triangulation)& aPolyTri,
+ TColgp_Array1OfDir& theNormals)
+{
+ Poly_Connect thePolyConnect(aPolyTri);
+ const TColgp_Array1OfPnt& aNodes = aPolyTri->Nodes();
+
+ if(aPolyTri->HasNormals())
+ {
+ // normals pre-computed in triangulation structure
+ const TShort_Array1OfShortReal& aNormals = aPolyTri->Normals();
+ const Standard_ShortReal* aNormArr = &(aNormals.Value(aNormals.Lower()));
+
+ for(Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter)
+ {
+ const Standard_Integer anId = 3 * (aNodeIter - aNodes.Lower());
+ const gp_Dir aNorm(aNormArr[anId + 0],
+ aNormArr[anId + 1],
+ aNormArr[anId + 2]);
+ theNormals(aNodeIter) = aNorm;
+ }
+
+ if(theFace.Orientation() == TopAbs_REVERSED)
+ {
+ for(Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter)
+ {
+ theNormals.ChangeValue(aNodeIter).Reverse();
+ }
+ }
+
+ return;
+ }
+
+ // take in face the surface location
+ const TopoDS_Face aZeroFace = TopoDS::Face(theFace.Located(TopLoc_Location()));
+ Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aZeroFace);
+ const Standard_Real aTol = Precision::Confusion();
+ Handle(TShort_HArray1OfShortReal) aNormals = new TShort_HArray1OfShortReal(1, aPolyTri->NbNodes() * 3);
+ const Poly_Array1OfTriangle& aTriangles = aPolyTri->Triangles();
+ const TColgp_Array1OfPnt2d* aNodesUV = aPolyTri->HasUVNodes() && !aSurf.IsNull()
+ ? &aPolyTri->UVNodes()
+ : NULL;
+ Standard_Integer aTri[3];
+
+ for(Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter)
+ {
+ // try to retrieve normal from real surface first, when UV coordinates are available
+ if(aNodesUV == NULL
+ || GeomLib::NormEstim(aSurf, aNodesUV->Value(aNodeIter), aTol, theNormals(aNodeIter)) > 1)
+ {
+ // compute flat normals
+ gp_XYZ eqPlan(0.0, 0.0, 0.0);
+
+ for(thePolyConnect.Initialize(aNodeIter); thePolyConnect.More(); thePolyConnect.Next())
+ {
+ aTriangles(thePolyConnect.Value()).Get(aTri[0], aTri[1], aTri[2]);
+ const gp_XYZ v1(aNodes(aTri[1]).Coord() - aNodes(aTri[0]).Coord());
+ const gp_XYZ v2(aNodes(aTri[2]).Coord() - aNodes(aTri[1]).Coord());
+ const gp_XYZ vv = v1 ^ v2;
+ const Standard_Real aMod = vv.Modulus();
+
+ if(aMod >= aTol)
+ {
+ eqPlan += vv / aMod;
+ }
+ }
+
+ const Standard_Real aModMax = eqPlan.Modulus();
+ theNormals(aNodeIter) = (aModMax > aTol) ? gp_Dir(eqPlan) : gp::DZ();
+ }
+
+ const Standard_Integer anId = (aNodeIter - aNodes.Lower()) * 3;
+ aNormals->SetValue(anId + 1, (Standard_ShortReal)theNormals(aNodeIter).X());
+ aNormals->SetValue(anId + 2, (Standard_ShortReal)theNormals(aNodeIter).Y());
+ aNormals->SetValue(anId + 3, (Standard_ShortReal)theNormals(aNodeIter).Z());
+ }
+
+ aPolyTri->SetNormals(aNormals);
+
+ if(theFace.Orientation() == TopAbs_REVERSED)
+ {
+ for(Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter)
+ {
+ theNormals.ChangeValue(aNodeIter).Reverse();
+ }
+ }
+}
+
//**************************************************************************
// Construction/Destruction
@@ -765,6 +861,9 @@ void ViewProviderPartExt::updateVisual(const TopoDS_Shape& inputShape)
// cycling through the poly mesh
const Poly_Array1OfTriangle& Triangles = mesh->Triangles();
const TColgp_Array1OfPnt& Nodes = mesh->Nodes();
+ TColgp_Array1OfDir Normals (Nodes.Lower(), Nodes.Upper());
+ GetNormals(actFace, mesh, Normals);
+
for (int g=1;g<=nbTriInFace;g++) {
// Get the triangle
Standard_Integer N1,N2,N3;
@@ -780,22 +879,23 @@ void ViewProviderPartExt::updateVisual(const TopoDS_Shape& inputShape)
// get the 3 points of this triangle
gp_Pnt V1(Nodes(N1)), V2(Nodes(N2)), V3(Nodes(N3));
- // transform the vertices to the place of the face
- if (!identity) {
+ // get the 3 normals of this triangle
+ gp_Dir NV1(Normals(N1)), NV2(Normals(N2)), NV3(Normals(N3));
+
+ // transform the vertices and normals to the place of the face
+ if(!identity) {
V1.Transform(myTransf);
V2.Transform(myTransf);
V3.Transform(myTransf);
+ NV1.Transform(myTransf);
+ NV2.Transform(myTransf);
+ NV3.Transform(myTransf);
}
-
- // calculating per vertex normals
- // Calculate triangle normal
- gp_Vec v1(V1.X(),V1.Y(),V1.Z()),v2(V2.X(),V2.Y(),V2.Z()),v3(V3.X(),V3.Y(),V3.Z());
- gp_Vec Normal = (v2-v1)^(v3-v1);
- // add the triangle normal to the vertex normal for all points of this triangle
- norms[faceNodeOffset+N1-1] += SbVec3f(Normal.X(),Normal.Y(),Normal.Z());
- norms[faceNodeOffset+N2-1] += SbVec3f(Normal.X(),Normal.Y(),Normal.Z());
- norms[faceNodeOffset+N3-1] += SbVec3f(Normal.X(),Normal.Y(),Normal.Z());
+ // add the normals for all points of this triangle
+ norms[faceNodeOffset+N1-1] += SbVec3f(NV1.X(),NV1.Y(),NV1.Z());
+ norms[faceNodeOffset+N2-1] += SbVec3f(NV2.X(),NV2.Y(),NV2.Z());
+ norms[faceNodeOffset+N3-1] += SbVec3f(NV3.X(),NV3.Y(),NV3.Z());
// set the vertices
verts[faceNodeOffset+N1-1].setValue((float)(V1.X()),(float)(V1.Y()),(float)(V1.Z()));