summaryrefslogtreecommitdiff
path: root/src/StdPrs/StdPrs_ToolShadedShape.cxx
blob: e67f6d6ccb6db6989631521419d7268052899b58 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
// File:	StdPrs_ToolShadedShape.cxx
// Created:	Wed Oct 27 09:29:14 1993
// Author:	Jean-LOuis FRENKEL
//		<jlf@stylox>


#include <StdPrs_ToolShadedShape.ixx>
#include <Poly_Triangulation.hxx>
#include <TColgp_HArray1OfPnt.hxx>
#include <TColgp_Array1OfPnt.hxx>
#include <TColgp_Array1OfPnt2d.hxx>
#include <Poly_Connect.hxx>
#include <TopAbs_Orientation.hxx>
#include <GeomAbs_SurfaceType.hxx>
//#include <CSLib.hxx>
#include <GeomLib.hxx>
#include <gp_Vec.hxx>
#include <Precision.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <BRep_Tool.hxx>
#include <TopLoc_Location.hxx>
#include <TShort_HArray1OfShortReal.hxx>
#include <TShort_Array1OfShortReal.hxx>

//=======================================================================
//function : IsClosed
//purpose  : 
//=======================================================================

Standard_Boolean StdPrs_ToolShadedShape::IsClosed(const TopoDS_Shape& aShape) 
{
  return aShape.Closed();
}


//=======================================================================
//function : Triangulation
//purpose  : 
//=======================================================================

Handle(Poly_Triangulation) StdPrs_ToolShadedShape::Triangulation
   (const TopoDS_Face& aFace,
    TopLoc_Location&   loc)
{
  return BRep_Tool::Triangulation(aFace, loc);
}


//=======================================================================
//function : Normal
//purpose  : 
//=======================================================================

void StdPrs_ToolShadedShape::Normal(const TopoDS_Face&  aFace,
				    Poly_Connect&       pc,
				    TColgp_Array1OfDir& Nor)
{
  const Handle(Poly_Triangulation)& T = pc.Triangulation();
  BRepAdaptor_Surface S;
  Standard_Boolean hasUV = T->HasUVNodes();
  Standard_Integer i;
  TopLoc_Location l;
  // move to zero
  TopoDS_Face zeroFace = TopoDS::Face(aFace.Located(TopLoc_Location()));
  //take in face the surface location
  
  //Handle(Geom_Surface) GS = BRep_Tool::Surface(aFace, l);
  Handle(Geom_Surface) GS = BRep_Tool::Surface(zeroFace);

  if(T->HasNormals()) {
    const TColgp_Array1OfPnt& Nodes = T->Nodes();
    const TShort_Array1OfShortReal& Normals = T->Normals();
    const Standard_ShortReal * arrN = &(Normals.Value(Normals.Lower()));
    for( i = Nodes.Lower(); i <= Nodes.Upper(); i++) {
      Standard_Integer in = 3*(i-Nodes.Lower());
      gp_Dir N(arrN[in + 0], arrN[in + 1], arrN[in + 2]);
      Nor(i) = N;
    }

    if (aFace.Orientation() == TopAbs_REVERSED) {
      for( i = Nodes.Lower(); i <= Nodes.Upper(); i++) {
	Nor.ChangeValue(i).Reverse();
      }
    }
  
    
  }
  else if (hasUV && !GS.IsNull()) {
    Standard_Integer nbNormVal  = T->NbNodes() * 3; 
    Handle(TShort_HArray1OfShortReal) Normals = 
      new TShort_HArray1OfShortReal(1, nbNormVal);

    const TColgp_Array1OfPnt2d& UVNodes = T->UVNodes();
    Standard_Real Tol = Precision::Confusion();
    for (i = UVNodes.Lower(); i <= UVNodes.Upper(); i++) {

      if(GeomLib::NormEstim(GS, UVNodes(i), Tol, Nor(i)) > 1) {
	const TColgp_Array1OfPnt& Nodes = T->Nodes();
	Standard_Integer n[3];
	const Poly_Array1OfTriangle& triangles = T->Triangles();

	gp_XYZ eqPlan(0, 0, 0);
	
	Standard_Real modmax = 0.;
	for (pc.Initialize(i);  pc.More(); pc.Next()) {
	  triangles(pc.Value()).Get(n[0], n[1], n[2]);
	  gp_XYZ v1(Nodes(n[1]).Coord()-Nodes(n[0]).Coord());
	  gp_XYZ v2(Nodes(n[2]).Coord()-Nodes(n[1]).Coord());
	  gp_XYZ vv = v1^v2;
	  Standard_Real mod = vv.Modulus();

	  if(mod < Tol) continue;

	  eqPlan += vv/mod;
	}

	modmax = eqPlan.Modulus();
	if(modmax > Tol) Nor(i) = gp_Dir(eqPlan);
	else Nor(i) = gp_Dir(0., 0., 1.);

      }

      Standard_Integer j = (i - UVNodes.Lower()) * 3;
      Normals->SetValue(j + 1, Standard_ShortReal(Nor(i).X()));
      Normals->SetValue(j + 2, Standard_ShortReal(Nor(i).Y()));
      Normals->SetValue(j + 3, Standard_ShortReal(Nor(i).Z()));

      if (aFace.Orientation() == TopAbs_REVERSED) (Nor(i)).Reverse();

    }

    T->SetNormals(Normals);    
  }
  else {
    Standard_Integer nbNormVal  = T->NbNodes() * 3; 
    Handle(TShort_HArray1OfShortReal) Normals = 
      new TShort_HArray1OfShortReal(1, nbNormVal);

    const TColgp_Array1OfPnt& Nodes = T->Nodes();
    Standard_Integer n[3];
    const Poly_Array1OfTriangle& triangles = T->Triangles();
    Standard_Real Tol = Precision::Confusion();

    for (i = Nodes.Lower(); i <= Nodes.Upper(); i++) {
      gp_XYZ eqPlan(0, 0, 0);
      for (pc.Initialize(i);  pc.More(); pc.Next()) {
	triangles(pc.Value()).Get(n[0], n[1], n[2]);
	gp_XYZ v1(Nodes(n[1]).Coord()-Nodes(n[0]).Coord());
	gp_XYZ v2(Nodes(n[2]).Coord()-Nodes(n[1]).Coord());
	gp_XYZ vv = v1^v2;
	Standard_Real mod = vv.Modulus();

	if(mod < Tol) continue;

	eqPlan += vv/mod;
      }

      Standard_Real modmax = eqPlan.Modulus();

      if(modmax > Tol) Nor(i) = gp_Dir(eqPlan);
      else Nor(i) = gp_Dir(0., 0., 1.);

      Nor(i) = gp_Dir(eqPlan);

      Standard_Integer j = (i - Nodes.Lower()) * 3;
      Normals->SetValue(j + 1, Standard_ShortReal(Nor(i).X()));
      Normals->SetValue(j + 2, Standard_ShortReal(Nor(i).Y()));
      Normals->SetValue(j + 3, Standard_ShortReal(Nor(i).Z()));

      if (aFace.Orientation() == TopAbs_REVERSED) (Nor(i)).Reverse();

    }

    T->SetNormals(Normals);
  }

  
}