0025418: Debug output to be limited to OCC development environment
[occt.git] / src / StlTransfer / StlTransfer.cxx
1 // Created on: 2000-06-23
2 // Created by: Sergey MOZOKHIN
3 // Copyright (c) 2000-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 //=======================================================================
17 #include <StlTransfer.ixx>
18 #include <Standard_ErrorHandler.hxx>
19 #include <Standard_Failure.hxx>
20 #include <TopoDS_Face.hxx>
21 #include <Poly_Connect.hxx>
22 #include <TColgp_Array1OfDir.hxx>
23 #include <Poly_Triangulation.hxx>
24 #include <BRepAdaptor_Surface.hxx>
25 #include <TopLoc_Location.hxx>
26 #include <Geom_Surface.hxx>
27 #include <BRep_Tool.hxx>
28 #include <gp_Vec.hxx>
29 #include <gp_Pnt.hxx>
30 #include <CSLib.hxx>
31 #include <TColgp_Array1OfPnt2d.hxx>
32 #include <CSLib.hxx>
33 #include <gp_Dir.hxx>
34 #include <gp_XYZ.hxx>
35 #include <BRepMesh_IncrementalMesh.hxx>
36 #include <TopAbs.hxx>
37 #include <Precision.hxx>
38 #include <TopExp_Explorer.hxx>
39 #include <TopoDS.hxx>
40 #include <TColgp_SequenceOfXYZ.hxx>
41 //function computes normals for surface
42
43 static void Normal(const TopoDS_Face&  aFace,
44                    Poly_Connect&       pc,
45                    TColgp_Array1OfDir& Nor)
46 {
47   const Handle(Poly_Triangulation)& T = pc.Triangulation();
48   BRepAdaptor_Surface S;
49   Standard_Boolean hasUV = T->HasUVNodes();
50   Standard_Integer i;
51   TopLoc_Location l;
52   Handle(Geom_Surface) GS = BRep_Tool::Surface(aFace, l);
53   
54   if (hasUV && !GS.IsNull()) {
55     Standard_Boolean OK = Standard_True;
56     gp_Vec D1U,D1V;
57     gp_Vec D2U,D2V,D2UV;
58     gp_Pnt P;
59     Standard_Real U, V;
60     CSLib_DerivativeStatus Status;
61     CSLib_NormalStatus NStat;
62     S.Initialize(aFace, Standard_False);
63     const TColgp_Array1OfPnt2d& UVNodes = T->UVNodes();
64     if (S.GetType() != GeomAbs_Plane) {
65       for (i = UVNodes.Lower(); i <= UVNodes.Upper(); i++) {
66         U = UVNodes(i).X();
67         V = UVNodes(i).Y();
68         S.D1(U,V,P,D1U,D1V);
69         CSLib::Normal(D1U,D1V,Precision::Angular(),Status,Nor(i));
70         if (Status != CSLib_Done) {
71           S.D2(U,V,P,D1U,D1V,D2U,D2V,D2UV);
72           CSLib::Normal(D1U,D1V,D2U,D2V,D2UV,Precision::Angular(),OK,NStat,Nor(i));
73         }
74         if (aFace.Orientation() == TopAbs_REVERSED) (Nor(i)).Reverse();
75       }
76     }
77     else {
78       gp_Dir NPlane;
79       U = UVNodes(UVNodes.Lower()).X();
80       V = UVNodes(UVNodes.Lower()).Y();
81       S.D1(U,V,P,D1U,D1V);
82       CSLib::Normal(D1U,D1V,Precision::Angular(),Status,NPlane);
83       if (Status != CSLib_Done) {
84         S.D2(U,V,P,D1U,D1V,D2U,D2V,D2UV);
85         CSLib::Normal(D1U,D1V,D2U,D2V,D2UV,Precision::Angular(),OK,NStat,NPlane);
86       }
87       if (aFace.Orientation() == TopAbs_REVERSED) NPlane.Reverse();
88       Nor.Init(NPlane);
89
90     }
91   }
92   else {
93     const TColgp_Array1OfPnt& Nodes = T->Nodes();
94     Standard_Integer n[3];
95     const Poly_Array1OfTriangle& triangles = T->Triangles();
96     
97     for (i = Nodes.Lower(); i <= Nodes.Upper(); i++) {
98       gp_XYZ eqPlan(0, 0, 0);
99       for (pc.Initialize(i);  pc.More(); pc.Next()) {
100         triangles(pc.Value()).Get(n[0], n[1], n[2]);
101         gp_XYZ v1(Nodes(n[1]).Coord()-Nodes(n[0]).Coord());
102         gp_XYZ v2(Nodes(n[2]).Coord()-Nodes(n[1]).Coord());
103         eqPlan += (v1^v2).Normalized();
104       }
105       Nor(i) = gp_Dir(eqPlan);
106       if (aFace.Orientation() == TopAbs_REVERSED) (Nor(i)).Reverse();
107     }
108   }
109   
110 }
111 void StlTransfer::BuildIncrementalMesh (const TopoDS_Shape&  Shape,
112                                                                                 const Standard_Real  Deflection,
113                                                                                 const Standard_Boolean  InParallel,
114                                                                                 const Handle(StlMesh_Mesh)& Mesh)
115 {
116   if (Deflection <= Precision::Confusion ()) {
117     Standard_ConstructionError::Raise ("StlTransfer::BuildIncrementalMesh");
118     }
119   
120   BRepMesh_IncrementalMesh aMesher(Shape, Deflection, Standard_False, 0.5, InParallel);
121   for (TopExp_Explorer itf(Shape,TopAbs_FACE); itf.More(); itf.Next()) {
122     TopoDS_Face face = TopoDS::Face(itf.Current());
123     TopLoc_Location Loc, loc;
124     Handle(Poly_Triangulation) theTriangulation = BRep_Tool::Triangulation(face, Loc);
125     if (theTriangulation.IsNull()) continue; //Meshing was not done for this face!
126     Poly_Array1OfTriangle theTriangles(1,theTriangulation->NbTriangles());
127     theTriangles.Assign(theTriangulation->Triangles());
128     Mesh->AddDomain (Deflection);
129     
130     TColgp_Array1OfPnt thePoints(1, theTriangulation->NbNodes());
131     thePoints.Assign(theTriangulation->Nodes());
132     //compute normal of face
133     const TColgp_Array1OfPnt& Nodes = theTriangulation->Nodes();
134     TColgp_Array1OfDir NORMAL(Nodes.Lower(), Nodes.Upper());
135     Poly_Connect pc(theTriangulation);
136     Normal(face, pc, NORMAL);
137     Standard_Integer i;
138     for(i=1;i<=thePoints.Length();i++) {
139       Standard_Real X1, Y1, Z1;
140       gp_Pnt p = thePoints.Value(i);
141       p.Transform(Loc.Transformation());
142       p.Coord (X1, Y1, Z1);
143       Mesh->AddVertex (X1, Y1, Z1);
144     }
145     try {
146       OCC_CATCH_SIGNALS
147       for (i=1;i<=theTriangles.Length();i++) {
148         Standard_Integer V1, V2, V3;
149         Poly_Triangle triangle = theTriangles.Value(i);
150         triangle.Get(V1, V2, V3);
151         gp_Pnt P1, P2, P3;
152         P1 = Mesh->Vertices(Mesh->NbDomains()).Value(V1);
153         P2 = Mesh->Vertices(Mesh->NbDomains()).Value(V2);
154         P3 = Mesh->Vertices(Mesh->NbDomains()).Value(V3);
155         gp_Vec average = NORMAL(V1);;   
156         
157         //check angle between vectors
158         gp_Vec V1V2(P1, P2), V2V3(P2, P3);
159         Standard_Integer A,B,C;
160         gp_Vec vec = V1V2^V2V3;
161         Standard_Real modul1, modul2;
162         modul1 = average.XYZ().Modulus();
163         modul2 = vec.XYZ().Modulus();
164         if (modul2>Precision::Confusion ()) vec.Divide(modul2);
165         A=V1;B=V2;C=V3;
166         //      vec.Transform(loc);
167         if (modul1>Precision::Confusion () && modul2>Precision::Confusion ()) {
168           Standard_Real an = vec.Angle(average);
169           if ( an > M_PI/2)  {
170             A = V3;B=V2;C=V1;
171           }
172           else {
173             A=V1;B=V2;C=V3;
174           }
175         }
176         Mesh->AddTriangle (A, B, C, average.X(), average.Y(), average.Z());
177       }
178     }
179     catch(Standard_Failure)
180       {
181 #ifdef OCCT_DEBUG
182         cout << "Fail in StlTransfer::BuildIncrementalMesh"   << endl;
183 #endif
184       }
185   }
186 }
187
188
189
190
191
192